Skip to content

Commit 4332b09

Browse files
authored
Replace print/verbose with standard logging (#337)
* logging: add NullHandler, replace prints with logging in auth and types - lyricsgenius/__init__.py: add NullHandler per library logging best practice - auth.py: replace print() with logger.warning/info - types/base.py: remove verbose param from save_lyrics(), replace prints with logger.debug - types/artist.py: deprecate verbose in add_song()/save_lyrics(), replace prints with logger.debug - types/song.py: deprecate verbose in save_lyrics(), remove pass-through to super() - types/album.py: deprecate verbose in save_lyrics(), remove pass-through to super() * logging: replace self.verbose/print with logger in genius.py - Remove self.verbose attribute entirely - Deprecate verbose __init__ param with DeprecationWarning shim - Replace all if self.verbose: print(...) guards with module-level logger calls at appropriate levels: - INFO: search progress, song count, artist name changes - DEBUG: skipped/rejected songs, alternative search attempts - WARNING: not-found results, missing lyrics sections * logging: wire --verbose flag to logging in CLI - Add module-level logger - Drop verbose=args.verbose from Genius() constructor call - --verbose now calls logging.basicConfig(level=DEBUG) so all lyricsgenius log records surface to stderr - Replace guarded print() for 'Saving lyrics' with logger.info() * tests: remove deprecated verbose= kwargs from all test calls * chore: bump version to 3.11.0 Replace print/verbose with standard Python logging (minor feature change). * logging: add enable_logging() convenience helper One-liner for scripts/notebooks that handles basicConfig with a sensible default format: lyricsgenius.enable_logging() lyricsgenius.enable_logging(logging.INFO) lyricsgenius.enable_logging(fmt='%(asctime)s %(levelname)s: %(message)s') Updates README and docs accordingly.
1 parent 55fa882 commit 4332b09

17 files changed

Lines changed: 203 additions & 136 deletions

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,18 @@ album.save_lyrics()
8888
There are various options configurable as parameters within the `Genius` class:
8989

9090
```python
91-
genius.verbose = False # Turn off status messages
9291
genius.remove_section_headers = True # Remove section headers (e.g. [Chorus]) from lyrics when searching
9392
genius.skip_non_songs = False # Include hits thought to be non-songs (e.g. track lists)
9493
genius.excluded_terms = ["(Remix)", "(Live)"] # Exclude songs with these words in their title
9594
```
9695

96+
By default the library is silent. To enable progress logging:
97+
98+
```python
99+
import lyricsgenius
100+
lyricsgenius.enable_logging() # defaults to DEBUG; pass logging.INFO for less output
101+
```
102+
97103
You can also call the package from the command line:
98104

99105
```bash

docs/src/usage.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ There are various options configurable as parameters within the
5454

5555
.. code:: python
5656
57-
# Turn off status messages
58-
genius.verbose = False
59-
6057
# Remove section headers (e.g. [Chorus]) from lyrics when searching
6158
genius.remove_section_headers = True
6259
@@ -66,6 +63,13 @@ There are various options configurable as parameters within the
6663
# Exclude songs with these words/phrases in their title (case-insensitive)
6764
genius.excluded_terms = ["(Remix)", "(Live)"]
6865
66+
By default the library is silent. To enable progress logging:
67+
68+
.. code:: python
69+
70+
import lyricsgenius
71+
lyricsgenius.enable_logging() # defaults to DEBUG; pass logging.INFO for less output
72+
6973
You can also call the package from the command line:
7074

7175
.. code:: bash

lyricsgenius/__init__.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,39 @@
33
# See LICENSE for details
44
"""A library that provides a Python interface to the Genius API"""
55

6+
import logging
67
import sys
78

89
assert sys.version_info[0] == 3, "LyricsGenius requires Python 3."
910
from lyricsgenius.api import API, PublicAPI
1011
from lyricsgenius.auth import OAuth2
1112
from lyricsgenius.genius import Genius
1213
from lyricsgenius.utils import auth_from_environment
14+
15+
# Standard library best practice for packages: add NullHandler so that log
16+
# records are silently discarded unless the *application* configures logging.
17+
logging.getLogger("lyricsgenius").addHandler(logging.NullHandler())
18+
19+
_LOG_FORMAT = "%(levelname)s %(name)s: %(message)s"
20+
21+
22+
def enable_logging(level: int = logging.DEBUG, fmt: str = _LOG_FORMAT) -> None:
23+
"""Enable lyricsgenius logging output to stderr.
24+
25+
A convenience wrapper around :func:`logging.basicConfig` that applies a
26+
sensible default format. Call this once near the top of your script before
27+
creating a :class:`Genius` instance.
28+
29+
Args:
30+
level: Logging level (default ``logging.DEBUG``). Use
31+
``logging.INFO`` to suppress debug-level messages.
32+
fmt: Log format string (default ``"%(levelname)s %(name)s: %(message)s"``).
33+
34+
Example::
35+
36+
import lyricsgenius
37+
lyricsgenius.enable_logging()
38+
lyricsgenius.enable_logging(logging.INFO)
39+
lyricsgenius.enable_logging(fmt="%(asctime)s %(levelname)s: %(message)s")
40+
"""
41+
logging.basicConfig(level=level, format=fmt)

lyricsgenius/__main__.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import argparse
2+
import logging
23
import os
34
from typing import Callable, Literal
45

56
from . import Genius
67
from .types import Album, Artist, Song
78

9+
logger = logging.getLogger(__name__)
10+
811
SearchResult = Song | Artist | Album
912

1013

@@ -37,8 +40,7 @@ def __call__(self, args: argparse.Namespace) -> None:
3740
if not args.save:
3841
print(result.to_text() if format == "txt" else result.to_json())
3942
else:
40-
if args.verbose:
41-
print(f"Saving lyrics in {format.upper()} format.")
43+
logger.info("Saving lyrics in %s format.", format.upper())
4244
result.save_lyrics(extension=format, overwrite=args.overwrite)
4345

4446

@@ -99,10 +101,19 @@ def main() -> None:
99101
help="Specify your Genius API access token (optional). If not provided, it will be read from the GENIUS_ACCESS_TOKEN environment variable.",
100102
)
101103
optional.add_argument(
102-
"-v", "--verbose", action="store_true", help="Turn on the API verbosity"
104+
"-v",
105+
"--verbose",
106+
action="store_true",
107+
help="Enable verbose logging output (sets log level to DEBUG)",
103108
)
104109
args: argparse.Namespace = parser.parse_args()
105110

111+
if args.verbose:
112+
logging.basicConfig(
113+
level=logging.DEBUG,
114+
format="%(levelname)s %(name)s: %(message)s",
115+
)
116+
106117
# Create an instance of the Genius class
107118
token: str | None = (
108119
args.token if args.token else os.environ.get("GENIUS_ACCESS_TOKEN", None)
@@ -112,7 +123,7 @@ def main() -> None:
112123
"Must provide access token either as an argument or as an environment variable."
113124
)
114125

115-
api = Genius(token, verbose=args.verbose, timeout=10)
126+
api = Genius(token, timeout=10)
116127
Searcher(api, args.search_type)(args)
117128

118129

lyricsgenius/auth.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import os
23
import webbrowser
34
from typing import Any, ClassVar, Self
@@ -8,6 +9,8 @@
89
from .types.types import ScopeT
910
from .utils import parse_redirected_url
1011

12+
logger = logging.getLogger(__name__)
13+
1114

1215
class OAuth2(Sender):
1316
"""Genius OAuth2 authorization flow.
@@ -45,7 +48,7 @@ def __init__(
4548
if os.environ.get("GENIUS_ACCESS_TOKEN"):
4649
super().__init__()
4750
else:
48-
print(
51+
logger.warning(
4952
"GENIUS_ACCESS_TOKEN not found in environment. "
5053
"Falling back to the public API (some features may be unavailable)."
5154
)
@@ -155,7 +158,7 @@ def prompt_user(self) -> str:
155158
156159
"""
157160
url = self.url
158-
print("Opening browser for Genius login...")
161+
logger.info("Opening browser for Genius login...")
159162
webbrowser.open(url)
160163
redirected = input("Please paste redirect URL: ").strip()
161164

0 commit comments

Comments
 (0)