Coverage for src/nendo/library/duckdb_library.py: 96%

28 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-30 09:47 +0100

1# -*- encoding: utf-8 -*- 

2"""Module implementing the NendoLibraryPlugin using DuckDB. 

3 

4A lightweight and fast implementation that is used as 

5Nendo's default library implementation. 

6""" 

7 

8import logging 

9from typing import Any, Optional 

10 

11from requests import Session 

12from sqlalchemy import Engine, create_engine 

13 

14from nendo import schema 

15from nendo.config import NendoConfig, get_settings 

16from nendo.library import model 

17from nendo.utils import play_signal 

18 

19from .sqlalchemy_library import SqlAlchemyNendoLibrary 

20 

21logger = logging.getLogger("nendo") 

22 

23 

24class DuckDBLibrary(SqlAlchemyNendoLibrary): 

25 """DuckDB-based implementation of the Nendo Library. 

26 

27 Inherits almost all functions from the SQLAlchemy implementation of the 

28 `NendoLibraryPlugin` and only differs in the way it connects to the database. 

29 """ 

30 

31 config: NendoConfig = None 

32 user: schema.NendoUser = None 

33 db: Engine = None 

34 storage_driver: schema.NendoStorage = None 

35 

36 def __init__( 

37 self, 

38 config: Optional[NendoConfig] = None, 

39 db: Optional[Engine] = None, 

40 session: Optional[Session] = None, 

41 **kwargs: Any, 

42 ) -> None: 

43 """Configure and connect to the database.""" 

44 super().__init__(**kwargs) 

45 self.config = config or get_settings() 

46 

47 if self.storage_driver is None: 

48 self.storage_driver = schema.NendoStorageLocalFS( 

49 library_path=self.config.library_path, user_id=self.config.user_id, 

50 ) 

51 

52 self._connect(db, session) 

53 

54 def _connect( 

55 self, 

56 db: Optional[Engine] = None, 

57 session: Optional[Session] = None, # noqa: ARG002 

58 ) -> None: 

59 """Open local DuckDB session.""" 

60 self.db = db or create_engine(f"duckdb:///{self.config.library_path}/nendo.db") 

61 model.Base.metadata.create_all(bind=self.db) 

62 self.user = self.default_user 

63 

64 def play(self, track: schema.NendoTrack) -> None: 

65 """Preview an audio track on mac & linux. 

66 

67 Args: 

68 track (NendoTrack): The track to play. 

69 """ 

70 play_signal(track.signal, track.sr)