mycelium-ai 0.5.0__py3-none-any.whl
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.
- mycelium/__init__.py +0 -0
- mycelium/api/__init__.py +0 -0
- mycelium/api/app.py +1147 -0
- mycelium/api/client_app.py +170 -0
- mycelium/api/generated_sources/__init__.py +0 -0
- mycelium/api/generated_sources/server_schemas/__init__.py +97 -0
- mycelium/api/generated_sources/server_schemas/api/__init__.py +5 -0
- mycelium/api/generated_sources/server_schemas/api/default_api.py +2473 -0
- mycelium/api/generated_sources/server_schemas/api_client.py +766 -0
- mycelium/api/generated_sources/server_schemas/api_response.py +25 -0
- mycelium/api/generated_sources/server_schemas/configuration.py +434 -0
- mycelium/api/generated_sources/server_schemas/exceptions.py +166 -0
- mycelium/api/generated_sources/server_schemas/models/__init__.py +41 -0
- mycelium/api/generated_sources/server_schemas/models/api_section.py +71 -0
- mycelium/api/generated_sources/server_schemas/models/chroma_section.py +69 -0
- mycelium/api/generated_sources/server_schemas/models/clap_section.py +75 -0
- mycelium/api/generated_sources/server_schemas/models/compute_on_server200_response.py +79 -0
- mycelium/api/generated_sources/server_schemas/models/compute_on_server_request.py +67 -0
- mycelium/api/generated_sources/server_schemas/models/compute_text_search_request.py +69 -0
- mycelium/api/generated_sources/server_schemas/models/config_request.py +81 -0
- mycelium/api/generated_sources/server_schemas/models/config_response.py +107 -0
- mycelium/api/generated_sources/server_schemas/models/create_playlist_request.py +71 -0
- mycelium/api/generated_sources/server_schemas/models/get_similar_by_track200_response.py +143 -0
- mycelium/api/generated_sources/server_schemas/models/library_stats_response.py +77 -0
- mycelium/api/generated_sources/server_schemas/models/logging_section.py +67 -0
- mycelium/api/generated_sources/server_schemas/models/media_server_section.py +67 -0
- mycelium/api/generated_sources/server_schemas/models/playlist_response.py +73 -0
- mycelium/api/generated_sources/server_schemas/models/plex_section.py +71 -0
- mycelium/api/generated_sources/server_schemas/models/processing_response.py +90 -0
- mycelium/api/generated_sources/server_schemas/models/save_config_response.py +73 -0
- mycelium/api/generated_sources/server_schemas/models/scan_library_response.py +75 -0
- mycelium/api/generated_sources/server_schemas/models/search_result_response.py +75 -0
- mycelium/api/generated_sources/server_schemas/models/server_section.py +67 -0
- mycelium/api/generated_sources/server_schemas/models/stop_processing_response.py +71 -0
- mycelium/api/generated_sources/server_schemas/models/task_status_response.py +87 -0
- mycelium/api/generated_sources/server_schemas/models/track_database_stats.py +75 -0
- mycelium/api/generated_sources/server_schemas/models/track_response.py +77 -0
- mycelium/api/generated_sources/server_schemas/models/tracks_list_response.py +81 -0
- mycelium/api/generated_sources/server_schemas/rest.py +329 -0
- mycelium/api/generated_sources/server_schemas/test/__init__.py +0 -0
- mycelium/api/generated_sources/server_schemas/test/test_api_section.py +57 -0
- mycelium/api/generated_sources/server_schemas/test/test_chroma_section.py +55 -0
- mycelium/api/generated_sources/server_schemas/test/test_clap_section.py +60 -0
- mycelium/api/generated_sources/server_schemas/test/test_compute_on_server200_response.py +52 -0
- mycelium/api/generated_sources/server_schemas/test/test_compute_on_server_request.py +53 -0
- mycelium/api/generated_sources/server_schemas/test/test_compute_text_search_request.py +54 -0
- mycelium/api/generated_sources/server_schemas/test/test_config_request.py +66 -0
- mycelium/api/generated_sources/server_schemas/test/test_config_response.py +97 -0
- mycelium/api/generated_sources/server_schemas/test/test_create_playlist_request.py +60 -0
- mycelium/api/generated_sources/server_schemas/test/test_default_api.py +150 -0
- mycelium/api/generated_sources/server_schemas/test/test_get_similar_by_track200_response.py +61 -0
- mycelium/api/generated_sources/server_schemas/test/test_library_stats_response.py +63 -0
- mycelium/api/generated_sources/server_schemas/test/test_logging_section.py +53 -0
- mycelium/api/generated_sources/server_schemas/test/test_media_server_section.py +53 -0
- mycelium/api/generated_sources/server_schemas/test/test_playlist_response.py +58 -0
- mycelium/api/generated_sources/server_schemas/test/test_plex_section.py +56 -0
- mycelium/api/generated_sources/server_schemas/test/test_processing_response.py +61 -0
- mycelium/api/generated_sources/server_schemas/test/test_save_config_response.py +58 -0
- mycelium/api/generated_sources/server_schemas/test/test_scan_library_response.py +61 -0
- mycelium/api/generated_sources/server_schemas/test/test_search_result_response.py +69 -0
- mycelium/api/generated_sources/server_schemas/test/test_server_section.py +53 -0
- mycelium/api/generated_sources/server_schemas/test/test_stop_processing_response.py +55 -0
- mycelium/api/generated_sources/server_schemas/test/test_task_status_response.py +71 -0
- mycelium/api/generated_sources/server_schemas/test/test_track_database_stats.py +60 -0
- mycelium/api/generated_sources/server_schemas/test/test_track_response.py +63 -0
- mycelium/api/generated_sources/server_schemas/test/test_tracks_list_response.py +75 -0
- mycelium/api/generated_sources/worker_schemas/__init__.py +61 -0
- mycelium/api/generated_sources/worker_schemas/api/__init__.py +5 -0
- mycelium/api/generated_sources/worker_schemas/api/default_api.py +318 -0
- mycelium/api/generated_sources/worker_schemas/api_client.py +766 -0
- mycelium/api/generated_sources/worker_schemas/api_response.py +25 -0
- mycelium/api/generated_sources/worker_schemas/configuration.py +434 -0
- mycelium/api/generated_sources/worker_schemas/exceptions.py +166 -0
- mycelium/api/generated_sources/worker_schemas/models/__init__.py +23 -0
- mycelium/api/generated_sources/worker_schemas/models/save_config_response.py +73 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_clap_section.py +75 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_client_api_section.py +69 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_client_section.py +79 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_config_request.py +73 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_config_response.py +89 -0
- mycelium/api/generated_sources/worker_schemas/models/worker_logging_section.py +67 -0
- mycelium/api/generated_sources/worker_schemas/rest.py +329 -0
- mycelium/api/generated_sources/worker_schemas/test/__init__.py +0 -0
- mycelium/api/generated_sources/worker_schemas/test/test_default_api.py +45 -0
- mycelium/api/generated_sources/worker_schemas/test/test_save_config_response.py +58 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_clap_section.py +60 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_client_api_section.py +55 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_client_section.py +65 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_config_request.py +59 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_config_response.py +89 -0
- mycelium/api/generated_sources/worker_schemas/test/test_worker_logging_section.py +53 -0
- mycelium/api/worker_models.py +99 -0
- mycelium/application/__init__.py +11 -0
- mycelium/application/job_queue.py +323 -0
- mycelium/application/library_management_use_cases.py +292 -0
- mycelium/application/search_use_cases.py +96 -0
- mycelium/application/services.py +340 -0
- mycelium/client.py +554 -0
- mycelium/client_config.py +251 -0
- mycelium/client_frontend_dist/404.html +1 -0
- mycelium/client_frontend_dist/_next/static/a4iyRdfsvkjdyMAK9cE9Y/_buildManifest.js +1 -0
- mycelium/client_frontend_dist/_next/static/a4iyRdfsvkjdyMAK9cE9Y/_ssgManifest.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/964-830f77d7ce1c2463.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/app/_not-found/page-d25eede5a9099bd3.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/app/layout-9b3d32f96dfe13b6.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/app/page-cc6bad295789134e.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/framework-7c95b8e5103c9e90.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/main-6b37be50736577a2.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/main-app-4153d115599d3126.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/pages/_app-0a0020ddd67f79cf.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/pages/_error-03529f2c21436739.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- mycelium/client_frontend_dist/_next/static/chunks/webpack-c81e624915b2ea70.js +1 -0
- mycelium/client_frontend_dist/_next/static/css/1eb7f0e2c78e0734.css +1 -0
- mycelium/client_frontend_dist/favicon.ico +0 -0
- mycelium/client_frontend_dist/file.svg +1 -0
- mycelium/client_frontend_dist/globe.svg +1 -0
- mycelium/client_frontend_dist/index.html +1 -0
- mycelium/client_frontend_dist/index.txt +20 -0
- mycelium/client_frontend_dist/next.svg +1 -0
- mycelium/client_frontend_dist/vercel.svg +1 -0
- mycelium/client_frontend_dist/window.svg +1 -0
- mycelium/config.py +346 -0
- mycelium/domain/__init__.py +13 -0
- mycelium/domain/models.py +71 -0
- mycelium/domain/repositories.py +98 -0
- mycelium/domain/worker.py +77 -0
- mycelium/frontend_dist/404.html +1 -0
- mycelium/frontend_dist/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/964-830f77d7ce1c2463.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/app/_not-found/page-d25eede5a9099bd3.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/app/layout-9b3d32f96dfe13b6.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/app/page-a761463485e0540b.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/framework-7c95b8e5103c9e90.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/main-6b37be50736577a2.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/main-app-4153d115599d3126.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/pages/_app-0a0020ddd67f79cf.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/pages/_error-03529f2c21436739.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- mycelium/frontend_dist/_next/static/chunks/webpack-c81e624915b2ea70.js +1 -0
- mycelium/frontend_dist/_next/static/css/1eb7f0e2c78e0734.css +1 -0
- mycelium/frontend_dist/_next/static/glVJ0yJSL0zWN7anTTG3_/_buildManifest.js +1 -0
- mycelium/frontend_dist/_next/static/glVJ0yJSL0zWN7anTTG3_/_ssgManifest.js +1 -0
- mycelium/frontend_dist/favicon.ico +0 -0
- mycelium/frontend_dist/file.svg +1 -0
- mycelium/frontend_dist/globe.svg +1 -0
- mycelium/frontend_dist/index.html +10 -0
- mycelium/frontend_dist/index.txt +20 -0
- mycelium/frontend_dist/next.svg +1 -0
- mycelium/frontend_dist/vercel.svg +1 -0
- mycelium/frontend_dist/window.svg +1 -0
- mycelium/infrastructure/__init__.py +17 -0
- mycelium/infrastructure/chroma_adapter.py +232 -0
- mycelium/infrastructure/clap_adapter.py +280 -0
- mycelium/infrastructure/plex_adapter.py +145 -0
- mycelium/infrastructure/track_database.py +467 -0
- mycelium/main.py +183 -0
- mycelium_ai-0.5.0.dist-info/METADATA +312 -0
- mycelium_ai-0.5.0.dist-info/RECORD +164 -0
- mycelium_ai-0.5.0.dist-info/WHEEL +5 -0
- mycelium_ai-0.5.0.dist-info/entry_points.txt +2 -0
- mycelium_ai-0.5.0.dist-info/licenses/LICENSE +21 -0
- mycelium_ai-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,251 @@
|
|
1
|
+
"""Client-specific YAML configuration management for Mycelium workers."""
|
2
|
+
|
3
|
+
import os
|
4
|
+
import logging
|
5
|
+
from dataclasses import dataclass, asdict
|
6
|
+
from pathlib import Path
|
7
|
+
from typing import Optional
|
8
|
+
|
9
|
+
import yaml
|
10
|
+
|
11
|
+
|
12
|
+
def get_user_data_dir() -> Path:
|
13
|
+
"""Get the user data directory for Mycelium (platform-specific)."""
|
14
|
+
if os.name == 'nt': # Windows
|
15
|
+
base_dir = os.getenv('LOCALAPPDATA', os.path.expanduser('~/AppData/Local'))
|
16
|
+
elif os.uname().sysname == 'Darwin': # macOS
|
17
|
+
base_dir = os.path.expanduser('~/Library/Application Support')
|
18
|
+
else: # Linux/Unix
|
19
|
+
base_dir = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
|
20
|
+
|
21
|
+
data_dir = Path(base_dir) / 'mycelium'
|
22
|
+
data_dir.mkdir(parents=True, exist_ok=True)
|
23
|
+
return data_dir
|
24
|
+
|
25
|
+
|
26
|
+
def get_user_log_dir() -> Path:
|
27
|
+
"""Get the user log directory for Mycelium (platform-specific)."""
|
28
|
+
if os.name == 'nt': # Windows
|
29
|
+
base_dir = os.getenv('LOCALAPPDATA', os.path.expanduser('~/AppData/Local'))
|
30
|
+
elif os.uname().sysname == 'Darwin': # macOS
|
31
|
+
base_dir = os.path.expanduser('~/Library/Logs')
|
32
|
+
else: # Linux/Unix
|
33
|
+
base_dir = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
|
34
|
+
|
35
|
+
log_dir = Path(base_dir) / 'mycelium'
|
36
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
37
|
+
return log_dir
|
38
|
+
|
39
|
+
|
40
|
+
def get_client_config_dir() -> Path:
|
41
|
+
"""Get the configuration directory for Mycelium client."""
|
42
|
+
if os.name == 'nt': # Windows
|
43
|
+
base_dir = os.getenv('APPDATA', os.path.expanduser('~/AppData/Roaming'))
|
44
|
+
else: # macOS and Linux/Unix
|
45
|
+
base_dir = os.path.expanduser('~/.config')
|
46
|
+
|
47
|
+
config_dir = Path(base_dir) / 'mycelium'
|
48
|
+
config_dir.mkdir(parents=True, exist_ok=True)
|
49
|
+
return config_dir
|
50
|
+
|
51
|
+
|
52
|
+
def get_client_config_file_path() -> Path:
|
53
|
+
"""Get the client configuration file path."""
|
54
|
+
return get_client_config_dir() / 'client_config.yml'
|
55
|
+
|
56
|
+
|
57
|
+
@dataclass
|
58
|
+
class CLAPConfig:
|
59
|
+
"""Configuration for CLAP model."""
|
60
|
+
model_id: str = "laion/larger_clap_music_and_speech"
|
61
|
+
target_sr: int = 48000
|
62
|
+
chunk_duration_s: int = 10
|
63
|
+
num_chunks: int = 3
|
64
|
+
max_load_duration_s: Optional[int] = 120
|
65
|
+
|
66
|
+
|
67
|
+
@dataclass
|
68
|
+
class ClientConfig:
|
69
|
+
"""Configuration for client worker connections."""
|
70
|
+
server_host: str = "localhost"
|
71
|
+
server_port: int = 8000
|
72
|
+
download_queue_size: int = 15
|
73
|
+
job_queue_size: int = 30
|
74
|
+
poll_interval: int = 5
|
75
|
+
download_workers: int = 10
|
76
|
+
gpu_batch_size: int = 4
|
77
|
+
|
78
|
+
|
79
|
+
@dataclass
|
80
|
+
class ClientAPIConfig:
|
81
|
+
"""Configuration for client API server."""
|
82
|
+
host: str = "localhost"
|
83
|
+
port: int = 3001
|
84
|
+
|
85
|
+
|
86
|
+
@dataclass
|
87
|
+
class LoggingConfig:
|
88
|
+
"""Configuration for logging system."""
|
89
|
+
level: str = "INFO"
|
90
|
+
format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
91
|
+
file: Optional[str] = None
|
92
|
+
|
93
|
+
|
94
|
+
@dataclass
|
95
|
+
class MyceliumClientConfig:
|
96
|
+
"""Client-specific configuration class containing only settings relevant to GPU workers."""
|
97
|
+
clap: CLAPConfig
|
98
|
+
client: ClientConfig
|
99
|
+
client_api: ClientAPIConfig
|
100
|
+
logging: LoggingConfig
|
101
|
+
|
102
|
+
@classmethod
|
103
|
+
def load_from_yaml(cls, config_path: Optional[Path] = None) -> "MyceliumClientConfig":
|
104
|
+
"""Load client configuration from YAML file only."""
|
105
|
+
if config_path is None:
|
106
|
+
config_path = get_client_config_file_path()
|
107
|
+
|
108
|
+
# Load YAML config if it exists
|
109
|
+
config_data = {}
|
110
|
+
config_exists = config_path.exists()
|
111
|
+
if config_exists:
|
112
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
113
|
+
config_data = yaml.safe_load(f) or {}
|
114
|
+
|
115
|
+
# Load from YAML only - no environment variable fallbacks
|
116
|
+
clap_config = CLAPConfig(
|
117
|
+
model_id=config_data.get("clap", {}).get("model_id", "laion/larger_clap_music_and_speech"),
|
118
|
+
target_sr=config_data.get("clap", {}).get("target_sr", 48000),
|
119
|
+
chunk_duration_s=config_data.get("clap", {}).get("chunk_duration_s", 10),
|
120
|
+
num_chunks=config_data.get("clap", {}).get("num_chunks", 3),
|
121
|
+
max_load_duration_s=config_data.get("clap", {}).get("max_load_duration_s", 120)
|
122
|
+
)
|
123
|
+
|
124
|
+
client_config = ClientConfig(
|
125
|
+
server_host=config_data.get("client", {}).get("server_host", "localhost"),
|
126
|
+
server_port=config_data.get("client", {}).get("server_port", 8000),
|
127
|
+
download_queue_size=config_data.get("client", {}).get("download_queue_size", 15),
|
128
|
+
job_queue_size=config_data.get("client", {}).get("job_queue_size", 30),
|
129
|
+
poll_interval=config_data.get("client", {}).get("poll_interval", 5),
|
130
|
+
download_workers=config_data.get("client", {}).get("download_workers", 10),
|
131
|
+
gpu_batch_size=config_data.get("client", {}).get("gpu_batch_size", 4),
|
132
|
+
)
|
133
|
+
|
134
|
+
client_api_config = ClientAPIConfig(
|
135
|
+
host=config_data.get("client_api", {}).get("host", "localhost"),
|
136
|
+
port=config_data.get("client_api", {}).get("port", 3001)
|
137
|
+
)
|
138
|
+
|
139
|
+
# Handle logging configuration with default log file path
|
140
|
+
logging_data = config_data.get("logging", {})
|
141
|
+
log_file = logging_data.get("file")
|
142
|
+
if log_file is None:
|
143
|
+
log_file = str(get_user_log_dir() / "mycelium_client.log")
|
144
|
+
|
145
|
+
logging_config = LoggingConfig(
|
146
|
+
level=logging_data.get("level", "INFO"),
|
147
|
+
format=logging_data.get("format", "%(asctime)s - %(name)s - %(levelname)s - %(message)s"),
|
148
|
+
file=log_file
|
149
|
+
)
|
150
|
+
|
151
|
+
cfg = cls(
|
152
|
+
clap=clap_config,
|
153
|
+
client=client_config,
|
154
|
+
client_api=client_api_config,
|
155
|
+
logging=logging_config
|
156
|
+
)
|
157
|
+
|
158
|
+
# If no config file existed, create one with current values for convenience
|
159
|
+
if not config_exists:
|
160
|
+
# Ensure config directory exists
|
161
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
162
|
+
try:
|
163
|
+
cfg.save_to_yaml(config_path)
|
164
|
+
except Exception:
|
165
|
+
# Best-effort; ignore failures to avoid blocking startup
|
166
|
+
pass
|
167
|
+
|
168
|
+
return cfg
|
169
|
+
|
170
|
+
def save_to_yaml(self, config_path: Optional[Path] = None) -> None:
|
171
|
+
"""Save client configuration to YAML file."""
|
172
|
+
if config_path is None:
|
173
|
+
config_path = get_client_config_file_path()
|
174
|
+
|
175
|
+
config_dict = {
|
176
|
+
"clap": asdict(self.clap),
|
177
|
+
"client": asdict(self.client),
|
178
|
+
"client_api": asdict(self.client_api),
|
179
|
+
"logging": asdict(self.logging)
|
180
|
+
}
|
181
|
+
|
182
|
+
with open(config_path, 'w', encoding='utf-8') as f:
|
183
|
+
yaml.dump(config_dict, f, default_flow_style=False, indent=2)
|
184
|
+
|
185
|
+
def to_dict(self) -> dict:
|
186
|
+
"""Convert client configuration to dictionary format."""
|
187
|
+
return {
|
188
|
+
"client": {
|
189
|
+
"server_host": self.client.server_host,
|
190
|
+
"server_port": self.client.server_port,
|
191
|
+
"download_queue_size": self.client.download_queue_size,
|
192
|
+
"job_queue_size": self.client.job_queue_size,
|
193
|
+
"poll_interval": self.client.poll_interval,
|
194
|
+
"download_workers": self.client.download_workers,
|
195
|
+
"gpu_batch_size": self.client.gpu_batch_size
|
196
|
+
},
|
197
|
+
"client_api": {
|
198
|
+
"host": self.client_api.host,
|
199
|
+
"port": self.client_api.port
|
200
|
+
},
|
201
|
+
"clap": {
|
202
|
+
"model_id": self.clap.model_id,
|
203
|
+
"target_sr": self.clap.target_sr,
|
204
|
+
"chunk_duration_s": self.clap.chunk_duration_s,
|
205
|
+
"num_chunks": self.clap.num_chunks,
|
206
|
+
"max_load_duration_s": self.clap.max_load_duration_s
|
207
|
+
},
|
208
|
+
"logging": {
|
209
|
+
"level": self.logging.level
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
def setup_logging(self) -> None:
|
214
|
+
"""Setup logging configuration."""
|
215
|
+
# Configure the root logger
|
216
|
+
level = getattr(logging, self.logging.level.upper(), logging.INFO)
|
217
|
+
|
218
|
+
# Create log directory if needed
|
219
|
+
log_file_path = Path(self.logging.file)
|
220
|
+
log_file_path.parent.mkdir(parents=True, exist_ok=True)
|
221
|
+
|
222
|
+
# Get the root logger
|
223
|
+
root_logger = logging.getLogger()
|
224
|
+
|
225
|
+
# Remove all existing handlers to ensure clean reconfiguration
|
226
|
+
for handler in root_logger.handlers[:]:
|
227
|
+
root_logger.removeHandler(handler)
|
228
|
+
handler.close()
|
229
|
+
|
230
|
+
# Set the new level on the root logger
|
231
|
+
root_logger.setLevel(level)
|
232
|
+
|
233
|
+
# Create and add new handlers
|
234
|
+
file_handler = logging.FileHandler(self.logging.file)
|
235
|
+
file_handler.setLevel(level)
|
236
|
+
file_handler.setFormatter(logging.Formatter(self.logging.format))
|
237
|
+
|
238
|
+
console_handler = logging.StreamHandler()
|
239
|
+
console_handler.setLevel(level)
|
240
|
+
console_handler.setFormatter(logging.Formatter(self.logging.format))
|
241
|
+
|
242
|
+
root_logger.addHandler(file_handler)
|
243
|
+
root_logger.addHandler(console_handler)
|
244
|
+
|
245
|
+
# Set log level for third-party libraries to reduce noise
|
246
|
+
logging.getLogger('chromadb').setLevel(logging.WARNING)
|
247
|
+
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
248
|
+
logging.getLogger('requests').setLevel(logging.WARNING)
|
249
|
+
|
250
|
+
# Disable verbose numba logging
|
251
|
+
logging.getLogger('numba.core').setLevel(logging.WARNING)
|
@@ -0,0 +1 @@
|
|
1
|
+
<!DOCTYPE html><!--a4iyRdfsvkjdyMAK9cE9Y--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/1eb7f0e2c78e0734.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-c81e624915b2ea70.js"/><script src="/_next/static/chunks/4bd1b696-cf72ae8a39fa05aa.js" async=""></script><script src="/_next/static/chunks/964-830f77d7ce1c2463.js" async=""></script><script src="/_next/static/chunks/main-app-4153d115599d3126.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Mycelium - AI Music Discovery</title><meta name="description" content="Discover your music collection like never before with AI-powered embeddings"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body class="antialiased"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-c81e624915b2ea70.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[7555,[],\"\"]\n3:I[1295,[],\"\"]\n4:I[9665,[],\"OutletBoundary\"]\n6:I[4911,[],\"AsyncMetadataOutlet\"]\n8:I[9665,[],\"ViewportBoundary\"]\na:I[9665,[],\"MetadataBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[8393,[],\"\"]\n:HL[\"/_next/static/css/1eb7f0e2c78e0734.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"a4iyRdfsvkjdyMAK9cE9Y\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/1eb7f0e2c78e0734.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"antialiased\",\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",[\"$\",\"$L6\",null,{\"promise\":\"$@7\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],null],[\"$\",\"$La\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$b\",null,{\"fallback\":null,\"children\":\"$Lc\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"e:I[8175,[],\"IconMark\"]\n7:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Mycelium - AI Music Discovery\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Discover your music collection like never before with AI-powered embeddings\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"16x16\"}],[\"$\",\"$Le\",\"3\",{}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"c:\"$7:metadata\"\n"])</script></body></html>
|
@@ -0,0 +1 @@
|
|
1
|
+
self.__BUILD_MANIFEST=function(e,r,t){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:3,errorRate:1e-4,numBits:58,numHashes:14,bitArray:[1,1,0,e,0,e,e,r,e,e,r,e,e,e,r,e,r,r,e,r,r,r,e,r,r,r,r,r,e,r,e,e,e,e,r,e,e,r,e,e,e,r,e,r,e,r,r,e,e,e,r,r,e,e,e,r,e,e]},__routerFilterDynamic:{numItems:r,errorRate:1e-4,numBits:r,numHashes:null,bitArray:[]},"/_error":["static/chunks/pages/_error-03529f2c21436739.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
@@ -0,0 +1 @@
|
|
1
|
+
self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB()
|