pymss 1.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.
- pymss-1.0/LICENSE +21 -0
- pymss-1.0/PKG-INFO +128 -0
- pymss-1.0/README.md +77 -0
- pymss-1.0/pymss/__init__.py +2 -0
- pymss-1.0/pymss/logger.py +93 -0
- pymss-1.0/pymss/modules/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit/core/__init__.py +744 -0
- pymss-1.0/pymss/modules/bandit/core/data/__init__.py +2 -0
- pymss-1.0/pymss/modules/bandit/core/data/_types.py +18 -0
- pymss-1.0/pymss/modules/bandit/core/data/augmentation.py +107 -0
- pymss-1.0/pymss/modules/bandit/core/data/augmented.py +35 -0
- pymss-1.0/pymss/modules/bandit/core/data/base.py +69 -0
- pymss-1.0/pymss/modules/bandit/core/data/dnr/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit/core/data/dnr/datamodule.py +74 -0
- pymss-1.0/pymss/modules/bandit/core/data/dnr/dataset.py +392 -0
- pymss-1.0/pymss/modules/bandit/core/data/dnr/preprocess.py +54 -0
- pymss-1.0/pymss/modules/bandit/core/data/musdb/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit/core/data/musdb/datamodule.py +77 -0
- pymss-1.0/pymss/modules/bandit/core/data/musdb/dataset.py +280 -0
- pymss-1.0/pymss/modules/bandit/core/data/musdb/preprocess.py +238 -0
- pymss-1.0/pymss/modules/bandit/core/loss/__init__.py +2 -0
- pymss-1.0/pymss/modules/bandit/core/loss/_complex.py +34 -0
- pymss-1.0/pymss/modules/bandit/core/loss/_multistem.py +45 -0
- pymss-1.0/pymss/modules/bandit/core/loss/_timefreq.py +113 -0
- pymss-1.0/pymss/modules/bandit/core/loss/snr.py +146 -0
- pymss-1.0/pymss/modules/bandit/core/metrics/__init__.py +9 -0
- pymss-1.0/pymss/modules/bandit/core/metrics/_squim.py +383 -0
- pymss-1.0/pymss/modules/bandit/core/metrics/snr.py +150 -0
- pymss-1.0/pymss/modules/bandit/core/model/__init__.py +3 -0
- pymss-1.0/pymss/modules/bandit/core/model/_spectral.py +58 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/__init__.py +23 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/bandsplit.py +139 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/core.py +661 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/maskestim.py +347 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/tfmodel.py +317 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/utils.py +583 -0
- pymss-1.0/pymss/modules/bandit/core/model/bsrnn/wrapper.py +882 -0
- pymss-1.0/pymss/modules/bandit/core/utils/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit/core/utils/audio.py +463 -0
- pymss-1.0/pymss/modules/bandit/model_from_config.py +31 -0
- pymss-1.0/pymss/modules/bandit_v2/__init__.py +0 -0
- pymss-1.0/pymss/modules/bandit_v2/bandit.py +367 -0
- pymss-1.0/pymss/modules/bandit_v2/bandsplit.py +130 -0
- pymss-1.0/pymss/modules/bandit_v2/film.py +25 -0
- pymss-1.0/pymss/modules/bandit_v2/maskestim.py +281 -0
- pymss-1.0/pymss/modules/bandit_v2/tfmodel.py +145 -0
- pymss-1.0/pymss/modules/bandit_v2/utils.py +523 -0
- pymss-1.0/pymss/modules/bs_roformer/__init__.py +2 -0
- pymss-1.0/pymss/modules/bs_roformer/attend.py +126 -0
- pymss-1.0/pymss/modules/bs_roformer/bs_roformer.py +621 -0
- pymss-1.0/pymss/modules/bs_roformer/mel_band_roformer.py +668 -0
- pymss-1.0/pymss/modules/demucs4ht.py +713 -0
- pymss-1.0/pymss/modules/ex_bi_mamba2.py +303 -0
- pymss-1.0/pymss/modules/look2hear/__init__.py +49 -0
- pymss-1.0/pymss/modules/look2hear/apollo.py +324 -0
- pymss-1.0/pymss/modules/look2hear/base_model.py +100 -0
- pymss-1.0/pymss/modules/mdx23c_tfc_tdf_v3.py +242 -0
- pymss-1.0/pymss/modules/scnet/__init__.py +1 -0
- pymss-1.0/pymss/modules/scnet/scnet.py +373 -0
- pymss-1.0/pymss/modules/scnet/separation.py +113 -0
- pymss-1.0/pymss/modules/scnet_unofficial/__init__.py +1 -0
- pymss-1.0/pymss/modules/scnet_unofficial/modules/__init__.py +3 -0
- pymss-1.0/pymss/modules/scnet_unofficial/modules/dualpath_rnn.py +228 -0
- pymss-1.0/pymss/modules/scnet_unofficial/modules/sd_encoder.py +285 -0
- pymss-1.0/pymss/modules/scnet_unofficial/modules/su_decoder.py +241 -0
- pymss-1.0/pymss/modules/scnet_unofficial/scnet.py +249 -0
- pymss-1.0/pymss/modules/scnet_unofficial/utils.py +135 -0
- pymss-1.0/pymss/modules/segm_models.py +255 -0
- pymss-1.0/pymss/modules/torchseg_models.py +255 -0
- pymss-1.0/pymss/modules/ts_bs_mamba2.py +319 -0
- pymss-1.0/pymss/modules/upernet_swin_transformers.py +228 -0
- pymss-1.0/pymss/separator.py +316 -0
- pymss-1.0/pymss/utils.py +230 -0
- pymss-1.0/pymss.egg-info/PKG-INFO +128 -0
- pymss-1.0/pymss.egg-info/SOURCES.txt +79 -0
- pymss-1.0/pymss.egg-info/dependency_links.txt +1 -0
- pymss-1.0/pymss.egg-info/requires.txt +21 -0
- pymss-1.0/pymss.egg-info/top_level.txt +1 -0
- pymss-1.0/setup.cfg +4 -0
- pymss-1.0/setup.py +60 -0
pymss-1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 KitsuneX07
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
pymss-1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pymss
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: Python package for music source separation.
|
|
5
|
+
Home-page: https://github.com/KitsuneX07/pymss
|
|
6
|
+
Author: KitsuneX07
|
|
7
|
+
Author-email: ghast1085654218@163.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/KitsuneX07/pymss/issues
|
|
10
|
+
Project-URL: Source Code, https://github.com/KitsuneX07/pymss
|
|
11
|
+
Project-URL: Documentation, https://github.com/KitsuneX07/pymss/blob/main/README.md
|
|
12
|
+
Keywords: music source separation,audio separation,music processing,machine learning,audio
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
26
|
+
Classifier: Operating System :: OS Independent
|
|
27
|
+
Requires-Python: >=3.7
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: pydub
|
|
31
|
+
Requires-Dist: numpy
|
|
32
|
+
Requires-Dist: torch
|
|
33
|
+
Requires-Dist: torchaudio
|
|
34
|
+
Requires-Dist: librosa
|
|
35
|
+
Requires-Dist: soundfile
|
|
36
|
+
Requires-Dist: tqdm
|
|
37
|
+
Requires-Dist: ml-collections
|
|
38
|
+
Requires-Dist: omegaconf
|
|
39
|
+
Requires-Dist: pyyaml
|
|
40
|
+
Requires-Dist: demucs
|
|
41
|
+
Requires-Dist: colorama
|
|
42
|
+
Requires-Dist: pytorch_lightning
|
|
43
|
+
Requires-Dist: asteroid
|
|
44
|
+
Requires-Dist: spafe
|
|
45
|
+
Requires-Dist: pedalboard
|
|
46
|
+
Requires-Dist: torch_audiomentations
|
|
47
|
+
Requires-Dist: beartype
|
|
48
|
+
Requires-Dist: rotary_embedding_torch
|
|
49
|
+
Requires-Dist: transformers
|
|
50
|
+
Requires-Dist: segmentation_models_pytorch
|
|
51
|
+
|
|
52
|
+
# pymss
|
|
53
|
+
|
|
54
|
+
Python package for music source separation.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
Example of using pip to install `pymss` package:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pip install pymss
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
Here's a simple example.
|
|
68
|
+
```python
|
|
69
|
+
from pymss MSSeparator, get_separation_logger
|
|
70
|
+
|
|
71
|
+
# init
|
|
72
|
+
separator = MSSeparator(
|
|
73
|
+
model_type='htdemucs',
|
|
74
|
+
model_path='path/to/model',
|
|
75
|
+
config_path='path/to/config',
|
|
76
|
+
device='cuda',
|
|
77
|
+
device_ids=[0],
|
|
78
|
+
output_format='wav',
|
|
79
|
+
use_tta=True,
|
|
80
|
+
store_dirs={
|
|
81
|
+
"vocals": "./output/vocals",
|
|
82
|
+
"other": None # None or missing this stem will result in no output file for this stem. This example will output the vocal's stem in ./output/vocals and ignoring the other(instrumental) stem. Making sure the key(s) match the config file.
|
|
83
|
+
},
|
|
84
|
+
audio_params={"wav_bit_depth": "FLOAT", "flac_bit_depth": "PCM_24", "mp3_bit_rate": "320k"}, # Can be omitted
|
|
85
|
+
logger=get_separation_logger(), # Can be omitted
|
|
86
|
+
debug=False, # Can be omitted
|
|
87
|
+
inference_params={
|
|
88
|
+
"batch_size": 4,
|
|
89
|
+
"num_overlap": 1,
|
|
90
|
+
"chunk_size": 1024,
|
|
91
|
+
"normalize": True
|
|
92
|
+
} # Can be omitted
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# process all audio files in the folder
|
|
96
|
+
separator.process_folder('path/to/input_folder')
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Parameters
|
|
100
|
+
|
|
101
|
+
- model_type: The type of model, e.g., 'htdemucs'. Must be one of
|
|
102
|
+
['bs_roformer',
|
|
103
|
+
'mel_band_roformer',
|
|
104
|
+
'segm_models',
|
|
105
|
+
'htdemucs',
|
|
106
|
+
'mdx23c',
|
|
107
|
+
'swin_upernet',
|
|
108
|
+
'bandit',
|
|
109
|
+
'bandit_v2',
|
|
110
|
+
'scnet',
|
|
111
|
+
'scnet_unofficial',
|
|
112
|
+
'torchseg',
|
|
113
|
+
'apollo',
|
|
114
|
+
'bs_mamba2']
|
|
115
|
+
- model_path: The path to the model file.
|
|
116
|
+
- config_path: The path to the configuration file.
|
|
117
|
+
- device: The type of device, default is 'auto'. Must be one of ['auto', 'cuda', 'mps', 'cpu']
|
|
118
|
+
- device_ids: List of device IDs, default is [0].
|
|
119
|
+
- output_format: The output audio format, default is 'wav'. Must be one of ['wav', 'flac', 'mp3']
|
|
120
|
+
- use_tta: Whether to use TTA, default is False. Using TTA will triple the processing time with a little bit improvement in quality.
|
|
121
|
+
- store_dirs: Storage directories, can be a single folder path or a dictionary with instrument keys.
|
|
122
|
+
- audio_params: Audio parameters including wav_bit_depth, flac_bit_depth, and mp3_bit_rate. Default is {"wav_bit_depth": "FLOAT", "flac_bit_depth": "PCM_24", "mp3_bit_rate": "320k"}.
|
|
123
|
+
- logger: Logger instance. Default is pymss.get_separation_logger()
|
|
124
|
+
- debug: Whether to enable debug mode, default is False.
|
|
125
|
+
- inference_params: Inference parameters including batch_size, num_overlap, chunk_size, and normalize. Default is all None (means all params are depended on the config file).
|
|
126
|
+
|
|
127
|
+
## Contributing
|
|
128
|
+
Contributions are welcome!
|
pymss-1.0/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# pymss
|
|
2
|
+
|
|
3
|
+
Python package for music source separation.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
Example of using pip to install `pymss` package:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pip install pymss
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
Here's a simple example.
|
|
17
|
+
```python
|
|
18
|
+
from pymss MSSeparator, get_separation_logger
|
|
19
|
+
|
|
20
|
+
# init
|
|
21
|
+
separator = MSSeparator(
|
|
22
|
+
model_type='htdemucs',
|
|
23
|
+
model_path='path/to/model',
|
|
24
|
+
config_path='path/to/config',
|
|
25
|
+
device='cuda',
|
|
26
|
+
device_ids=[0],
|
|
27
|
+
output_format='wav',
|
|
28
|
+
use_tta=True,
|
|
29
|
+
store_dirs={
|
|
30
|
+
"vocals": "./output/vocals",
|
|
31
|
+
"other": None # None or missing this stem will result in no output file for this stem. This example will output the vocal's stem in ./output/vocals and ignoring the other(instrumental) stem. Making sure the key(s) match the config file.
|
|
32
|
+
},
|
|
33
|
+
audio_params={"wav_bit_depth": "FLOAT", "flac_bit_depth": "PCM_24", "mp3_bit_rate": "320k"}, # Can be omitted
|
|
34
|
+
logger=get_separation_logger(), # Can be omitted
|
|
35
|
+
debug=False, # Can be omitted
|
|
36
|
+
inference_params={
|
|
37
|
+
"batch_size": 4,
|
|
38
|
+
"num_overlap": 1,
|
|
39
|
+
"chunk_size": 1024,
|
|
40
|
+
"normalize": True
|
|
41
|
+
} # Can be omitted
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# process all audio files in the folder
|
|
45
|
+
separator.process_folder('path/to/input_folder')
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Parameters
|
|
49
|
+
|
|
50
|
+
- model_type: The type of model, e.g., 'htdemucs'. Must be one of
|
|
51
|
+
['bs_roformer',
|
|
52
|
+
'mel_band_roformer',
|
|
53
|
+
'segm_models',
|
|
54
|
+
'htdemucs',
|
|
55
|
+
'mdx23c',
|
|
56
|
+
'swin_upernet',
|
|
57
|
+
'bandit',
|
|
58
|
+
'bandit_v2',
|
|
59
|
+
'scnet',
|
|
60
|
+
'scnet_unofficial',
|
|
61
|
+
'torchseg',
|
|
62
|
+
'apollo',
|
|
63
|
+
'bs_mamba2']
|
|
64
|
+
- model_path: The path to the model file.
|
|
65
|
+
- config_path: The path to the configuration file.
|
|
66
|
+
- device: The type of device, default is 'auto'. Must be one of ['auto', 'cuda', 'mps', 'cpu']
|
|
67
|
+
- device_ids: List of device IDs, default is [0].
|
|
68
|
+
- output_format: The output audio format, default is 'wav'. Must be one of ['wav', 'flac', 'mp3']
|
|
69
|
+
- use_tta: Whether to use TTA, default is False. Using TTA will triple the processing time with a little bit improvement in quality.
|
|
70
|
+
- store_dirs: Storage directories, can be a single folder path or a dictionary with instrument keys.
|
|
71
|
+
- audio_params: Audio parameters including wav_bit_depth, flac_bit_depth, and mp3_bit_rate. Default is {"wav_bit_depth": "FLOAT", "flac_bit_depth": "PCM_24", "mp3_bit_rate": "320k"}.
|
|
72
|
+
- logger: Logger instance. Default is pymss.get_separation_logger()
|
|
73
|
+
- debug: Whether to enable debug mode, default is False.
|
|
74
|
+
- inference_params: Inference parameters including batch_size, num_overlap, chunk_size, and normalize. Default is all None (means all params are depended on the config file).
|
|
75
|
+
|
|
76
|
+
## Contributing
|
|
77
|
+
Contributions are welcome!
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from colorama import Fore, Style, init
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
init(autoreset=True)
|
|
7
|
+
|
|
8
|
+
MAX_LOG = 100
|
|
9
|
+
LOG_DIR = "logs"
|
|
10
|
+
|
|
11
|
+
class ColorFormatter(logging.Formatter):
|
|
12
|
+
def format(self, record):
|
|
13
|
+
record.pathname = os.path.relpath(record.pathname)
|
|
14
|
+
log_msg = super().format(record)
|
|
15
|
+
|
|
16
|
+
if record.levelname == "INFO":
|
|
17
|
+
log_msg = log_msg.replace("INFO", f"{Fore.GREEN}INFO{Style.RESET_ALL}")
|
|
18
|
+
elif record.levelname == "DEBUG":
|
|
19
|
+
log_msg = log_msg.replace("DEBUG", f"{Fore.BLUE}DEBUG{Style.RESET_ALL}")
|
|
20
|
+
elif record.levelname == "WARNING":
|
|
21
|
+
log_msg = log_msg.replace("WARNING", f"{Fore.YELLOW}WARNING{Style.RESET_ALL}")
|
|
22
|
+
elif record.levelname == "ERROR":
|
|
23
|
+
log_msg = log_msg.replace("ERROR", f"{Fore.RED}ERROR{Style.RESET_ALL}")
|
|
24
|
+
elif record.levelname == "CRITICAL":
|
|
25
|
+
log_msg = log_msg.replace("CRITICAL", f"{Fore.MAGENTA}CRITICAL{Style.RESET_ALL}")
|
|
26
|
+
|
|
27
|
+
return log_msg
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def manage_log_files(log_dir, max_log):
|
|
31
|
+
log_files = [f for f in os.listdir(log_dir) if f.endswith(".log")]
|
|
32
|
+
|
|
33
|
+
def parse_date(filename):
|
|
34
|
+
for fmt in ("%Y-%m-%d", "%Y-%m-%d_%H-%M-%S"):
|
|
35
|
+
try:
|
|
36
|
+
return datetime.strptime(filename.split(".")[0], fmt)
|
|
37
|
+
except ValueError:
|
|
38
|
+
continue
|
|
39
|
+
return datetime.min
|
|
40
|
+
|
|
41
|
+
log_files = sorted(log_files, key=parse_date)
|
|
42
|
+
|
|
43
|
+
while len(log_files) > max_log:
|
|
44
|
+
try:
|
|
45
|
+
oldest_file = log_files.pop(0)
|
|
46
|
+
os.remove(os.path.join(log_dir, oldest_file))
|
|
47
|
+
except: pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def set_log_level(logger, level):
|
|
51
|
+
logger.console_handler.setLevel(level)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_separation_logger(console_level=logging.INFO, enable_file_log=False, max_log=MAX_LOG):
|
|
55
|
+
logger = logging.getLogger("logger")
|
|
56
|
+
|
|
57
|
+
if logger.hasHandlers():
|
|
58
|
+
return logger
|
|
59
|
+
|
|
60
|
+
logger.setLevel(logging.DEBUG)
|
|
61
|
+
|
|
62
|
+
console_handler = logging.StreamHandler()
|
|
63
|
+
console_handler.setLevel(console_level)
|
|
64
|
+
formatter = ColorFormatter(fmt="%(asctime)s.%(msecs)03d [%(levelname)s] [%(pathname)s:%(lineno)d] %(message)s", datefmt="%H:%M:%S")
|
|
65
|
+
console_handler.setFormatter(formatter)
|
|
66
|
+
|
|
67
|
+
logger.addHandler(console_handler)
|
|
68
|
+
|
|
69
|
+
if enable_file_log:
|
|
70
|
+
os.makedirs(LOG_DIR, exist_ok=True)
|
|
71
|
+
log_filename = datetime.now().strftime("%Y-%m-%d_%H-%M-%S.log")
|
|
72
|
+
file_path = os.path.join(LOG_DIR, log_filename)
|
|
73
|
+
|
|
74
|
+
file_handler = logging.FileHandler(file_path, mode='a', encoding='utf-8')
|
|
75
|
+
file_handler.setLevel(logging.DEBUG)
|
|
76
|
+
file_formatter = logging.Formatter(fmt="%(asctime)s.%(msecs)03d [%(levelname)s] [%(pathname)s:%(lineno)d] %(message)s", datefmt="%H:%M:%S")
|
|
77
|
+
file_handler.setFormatter(file_formatter)
|
|
78
|
+
|
|
79
|
+
logger.addHandler(file_handler)
|
|
80
|
+
manage_log_files(LOG_DIR, max_log)
|
|
81
|
+
|
|
82
|
+
logger.console_handler = console_handler
|
|
83
|
+
|
|
84
|
+
return logger
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
if __name__ == "__main__":
|
|
88
|
+
logger = get_separation_logger(console_level=logging.INFO, enable_file_log=False)
|
|
89
|
+
logger.debug("This is a debug message.")
|
|
90
|
+
logger.info("This is an info message.")
|
|
91
|
+
logger.warning("This is a warning message.")
|
|
92
|
+
logger.error("This is an error message.")
|
|
93
|
+
logger.critical("This is a critical message.")
|
|
File without changes
|
|
File without changes
|