question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

lyrics: Crash when BeautifulSoup is not installed

See original GitHub issue

Problem

The Lyrics plugin throws an error/crashes when ran without BeautifulSoup installed.

Terminal output

I currently can’t run a verbose command because Beets is dragging itself through finding lyrics for many many albums.

The following error is displayed in Terminal when running:

$ beets lyrics artist song
/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/util/confit.py:21: UserWarning: beets.util.confit is deprecated; use confuse instead
  warnings.warn("beets.util.confit is deprecated; use confuse instead")
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/bin/beet", line 11, in <module>
    load_entry_point('beets==1.5.0', 'console_scripts', 'beet')()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1291, in main
    _raw_main(args)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1274, in _raw_main
    subcommands, plugins, lib = _setup(options, lib)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1153, in _setup
    plugins = _load_plugins(options, config)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/ui/__init__.py", line 1139, in _load_plugins
    plugins.send("pluginload")
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 497, in send
    for handler in event_handlers()[event]:
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 480, in event_handlers
    for plugin in find_plugins():
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/plugins.py", line 315, in find_plugins
    _instances[cls] = cls()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beetsplug/lyrics.py", line 736, in __init__
    sources = self.sanitize_bs_sources(sources)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beetsplug/lyrics.py", line 763, in sanitize_bs_sources
    if source.REQUIRES_BS:
AttributeError: 'str' object has no attribute 'REQUIRES_BS'

After installing BeautifulSoup the output is

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/beets/util/confit.py:21: UserWarning: beets.util.confit is deprecated; use confuse instead
  warnings.warn("beets.util.confit is deprecated; use confuse instead")

Andrew writes:

We’re supposed to silently fix up the configuration when BeautifulSoup is not installed; not crash with a traceback. Glancing at the code, I do see the mistake.

Setup

  • OS: macOS 10.13.6
  • Python version: 3.7
  • beets version: 1.5
  • Turning off plugins made problem go away (yes/no):

My configuration (output of beet config) is:

library: ~/Music/Beets/musiclibrary.db
directory: /Volumes/Tunez

import:
    write: yes
    copy: yes
    move: no
    link: no
    hardlink: no
    delete: no
    resume: ask
    incremental: no
    incremental_skip_later: no
    from_scratch: no
    quiet_fallback: skip
    none_rec_action: ask
    timid: no
    log:
    autotag: yes
    quiet: no
    singletons: no
    default_action: apply
    languages: []
    detail: no
    flat: no
    group_albums: no
    pretend: false
    search_ids: []
    duplicate_action: remove
    bell: no
    set_fields: {}

clutter: ["Thumbs.DB", ".DS_Store"]
ignore: [".*", "*~", "System Volume Information", "lost+found"]
ignore_hidden: yes

replace:
    '[\\/]': _
    '^\.': _
    '[\x00-\x1f]': _
    '[<>:"\?\*\|]': ''
    '\.$': _
    '\s+$': ''
    '^\s+': ''
    '^-': _
path_sep_replace: _
asciify_paths: false
art_filename: cover
max_filename_length: 0

aunique:
    keys: albumartist album
    disambiguators: albumtype year samplerate label catalognum albumdisambig releasegroupdisambig
    bracket: '()'

plugins: 
    - inline
    - the
    - lastgenre
    - discogs
    - chroma
    - acousticbrainz
    - fromfilename
    - fetchart
    - embedart
    - ftintitle
    - edit
    - info
    - missing
    - types
    - convert
    - plexupdate
    - web
    - unimported
    - keyfinder
    - fuzzy
    - spotify
    - describe
    - bpmanalyser
    - lyrics
#    - smartplaylist
#    - goingrunning
pluginpath: 
    - /Users/xxxxxxxx/Documents/BeetsPluginDescribe/beetsplug
threaded: yes
timeout: 5.0
per_disc_numbering: no
verbose: 0
terminal_encoding:
original_date: no
artist_credit: no
id3v23: no
va_name: "Various Artists"

zero:
    fields: comments
    update_database: true

# Inline plugin template
item_fields:
  multidisc: 1 if disctotal > 1 else 0
  my_samplerate: round(samplerate / 1000)
  is_flac: 1 if format == "FLAC" else 0
album_fields:  
  format: |
       formatList = []
       for item in items:
           formatList.append(item.format)
       return formatList
  av_bitrate: |
       total = 0
       for item in items:
           total += item.bitrate
       return round(total / len(items) / 1000)
  album_bitdepth:  |
       total = 0
       for item in items:
           total += item.bitdepth
       return round(total / len(items))
  album_samplerate:  |
       total = 0
       for item in items:
           total += item.samplerate
       return round(total / len(items) / 1000)
  is_1644: |
       bd = 0
       sr = 0
       br = 0
       for item in items:
           bd += item.bitdepth
           sr += item.samplerate
           br += item.bitrate
       bd = round(bd / len(items))
       sr = round(sr / len(items) / 1000)
       br = round(br / len(items) / 1000)
       return 1 if bd == 16 and sr == 44 and br > 320 else 0

ui:
    terminal_width: 80
    length_diff_thresh: 10.0
    color: yes
    colors:
        text_success: green
        text_warning: yellow
        text_error: red
        text_highlight: red
        text_highlight_minor: lightgray
        action_default: turquoise
        action: blue

format_item: $artist - $album - $title
format_album: $albumartist - $album
time_format: '%Y-%m-%d %H:%M:%S'
format_raw_length: no

sort_album: albumartist+ album+
sort_item: artist+ album+ disc+ track+
sort_case_insensitive: yes

paths:
#  default: 'Albums/%the{$albumartist}/$album (%if{$original_year,$original_year}) %aunique{albumartist album year, albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $title'
  default: 'Albums/%the{$albumartist}/%if{$original_year,$original_year} - $album %aunique{albumartist album year, albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $album_bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $title'
  dancetrack:1: 'Singles Dance/$artist - $title (%if{$original_year,$original_year}) %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig$ $year)}($bpm bpm)'
  artistsingles:1: 'Albums/%the{$albumartist}/$album/$title'
  custcomp:1: 'Compilations/$album/$track - $artist - $title'
  custcompmin:1: 'Compilations/$album/$artist - $title'
  singleton: 'Singles/$artist - $title %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig$ $year)}'
  comp: 'Albums/%the{$albumartist}/$album (%if{$original_year,$original_year}) %aunique{albumartist album year, albumtype label catalognum albumdisambig}%if{$albumdisambig,($albumdisambig $year) }%if{$is_1644,,%if{$is_flac,($format $bitdepth-$album_samplerate),($format $av_bitrate)}}/%if{$multidisc,$disc-}$track - $artist - $title'


statefile: state.pickle

musicbrainz:
    host: musicbrainz.org
    ratelimit: 1
    ratelimit_interval: 1.0
    searchlimit: 5

match:
    strong_rec_thresh: 0.04
    medium_rec_thresh: 0.25
    rec_gap_thresh: 0.25
    max_rec:
        missing_tracks: medium
        unmatched_tracks: medium
    distance_weights:
        source: 2.0
        artist: 3.0
        album: 3.0
        media: 1.0
        mediums: 1.0
        year: 1.0
        country: 0.5
        label: 0.5
        catalognum: 0.5
        albumdisambig: 0.5
        album_id: 5.0
        tracks: 2.0
        missing_tracks: 0.9
        unmatched_tracks: 0.6
        track_title: 3.0
        track_artist: 2.0
        track_index: 1.0
        track_length: 2.0
        track_id: 5.0
    preferred:
        countries: []
        media: ['Digital Media|File' , 'CD']
        original_year: no
    ignored: []
    required: []
    ignored_media: []
    ignore_data_tracks: yes
    ignore_video_tracks: yes
    track_length_grace: 10
    track_length_max: 30
    
chroma:
    auto: no
    
fetchart:
    auto: yes
    cautious: no
    cover_names: cover front art album folder
    minwidth: 290
    maxwidth: 1050
    sources: itunes amazon albumart lastfm fanart filesystem coverart 
    fanarttv_key: xxxxxxxxxxxxx
    lastfm_key: xxxxxxxxxxxx
    
acoustid: 
    apikey: xxxxxxxxx
   
embedart:
    auto: yes
    ifempty: no   
    
lastgenre:
    auto: yes
    canonical: no
    count: 1
    force: yes
    source: album
    whitelist: yes
    min_weight: 10
    fallback:
    separator: ', '
    prefer_specific: no
    
types:
    av_bitrate: int
    my_samplerate: int
    bitdepth: int
    album_bitdepth: int
    album_samplerate: int
    rating: int
    
convert:
    dest: ~/Music/BeetExports
    command: ffmpeg -i $source -y -vn -aq 0 $dest    
    extension: mp3
    format: mp3
    never_convert_lossy_files: yes

plex:
    host: localhost
    port: 32400
    token: xxxxxxxxxxxxxx
    
lastfm:
    user: xxxxxxxxxx
    
smartplaylist:
    playlist_dir: /Users/Shared/Music/Playlists
    auto: no
    playlists:
        - name: 'favorites.m3u' 
          query: rating:4..5
        - name: 'danceable.m3u'
          query: 
            - danceable:0.8..
        - name: 'acoustic.m3u'
          query: 
            - mood_acoustic:0.8..
        - name: 'aggresive.m3u'
          query: 
            - mood_aggresive:0.8..
        - name: 'electronic.m3u'
          query: 
            - mood_electronic:0.8..
        - name: 'danceable.m3u'
          query: 
            - danceable:0.8..
        - name: 'happy.m3u'
          query: 
            - mood_happy:0.8..           
        - name: 'party.m3u'
          query: 
            - mood_party:0.8.. 
        - name: 'relaxed.m3u'
          query: 
            - mood_relaxed:0.8..                   
        - name: 'sad.m3u'
          query: 
            - mood_sad:0.8..

spotify:
    mode: list
    show_failures: on
    tiebreak: first
    
bpmanalyser:
    auto: no
    dry-run: no
    write: yes
    force: no
    quiet: no
    
goingrunning:
  targets:
    subsonic_m3u:
      device_root: /Users/Shared/Music/Playlists
      device_path: 
      clean_target: yes
      generate_playlist: yes
      copy_files: no
  trainings:
    10K:
      use_flavours: [intensity_low, intensity_high, running]
      duration: 180
      target: subsonic_m3u
  flavours:
    intensity_low:
      bpm: 87..88
    intensity_high:
      bpm: 175..177
    running:
      genre: [electronic, hip hop, funk, trip hop, house]

web:
    host: 0.0.0.0
    cors: 'http://localhost:3000'
    
lyrics:
    auto: yes
    google_API_key: xxxxxxxxxxxxxxxxx
    google_engine_ID: 009217259823014548361:lndtuqkycfu
    
unimported:
    ignore_extensions: mid wav

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ctruedencommented, Oct 1, 2021

@sampsyo Side question about that: I notice the docs don’t mention the pattern:

git clone git://github.com/beetbox/beets
cd beets
pip install -e .

to install beets from source in editable mode. Should we add it? The advantage is that you can then hack on your beets working copy, and the changes are immediately reflected in your environment without needing to run python setup.py install every time. This is how I’ve been developing my beets plugins, and I find it very convenient. Or is there some downside to pip install -e that I don’t know (I’m not super expert at python)?

Edit: Reading more carefully, I see that pip install -e is the third option listed… but using the “automatic source checkout” approach. So I guess the distinction here is merely whether you clone it manually yourself, and therefore get to decide where the sources go? *shrug*

Edit 2: I filed #4084 suggesting an addition to the FAQ about pip install -e .. Please feel free to close if it’s not to your liking.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Beautiful Soup crashes Python process - Stack Overflow
My Python process that processes multiple pages on one website crashes on the line: soup = BeautifulSoup(cleaned_html, "lxml").
Read more >
Beautiful Soup Tutorial - Web Scraping in Python - YouTube
The Beautiful Soup module is used for web scraping in Python. Learn how to use the Beautiful Soup and Requests modules in this...
Read more >
How to Build a Web Scraping Pipeline Using BeautifulSoup
Create a web scraping pipeline in Python; Navigate and parse HTML code; Use Beautiful Soup and Requests to fetch and extract data from...
Read more >
Changelog — beets 1.6.0 documentation - Read the Docs
Lyrics Plugin: The plugin no longer crashes in the Genius source when BeautifulSoup is not found. Instead, it just logs a message and...
Read more >
Web-scraping with Beautiful Soup - DAsH - O'Malley Library
Some sites block you from web-scraping, but most do not. ... Beautiful Soup: Installation and Basics; Identifying Target Data with Developer ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found