Skip to content

Commit c91eeb5

Browse files
committed
feat: enhance paperless API configuration handling and validation
Fixes #35
1 parent 0bbcb2d commit c91eeb5

File tree

1 file changed

+69
-12
lines changed

1 file changed

+69
-12
lines changed

main.py

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,58 @@
5454
logger.info(f"Loaded PAPERLESS_HOST: {os.getenv('PAPERLESS_HOST')}")
5555
logger.info(f"Loaded PAPERLESS_API_TOKEN: {'[SET]' if os.getenv('PAPERLESS_API_TOKEN') else '[NOT SET]'}")
5656

57+
58+
def _is_missing_or_placeholder(value: Optional[str]) -> bool:
59+
"""Return True for empty values and common sample placeholders."""
60+
if not value:
61+
return True
62+
63+
normalized = value.strip().lower()
64+
if not normalized:
65+
return True
66+
67+
placeholder_values = {
68+
"your-api-token",
69+
"your-api-key",
70+
"your-api-url",
71+
"your-paperless-instance",
72+
"https://your-paperless-instance",
73+
"http://your-paperless-instance",
74+
"changeme",
75+
"replace-me",
76+
"none",
77+
"null",
78+
}
79+
return normalized in placeholder_values
80+
81+
82+
def _resolve_paperless_config() -> Tuple[Optional[str], Optional[str]]:
83+
"""Resolve paperless URL/token from supported env var aliases."""
84+
paperless_api_url = (
85+
os.getenv("PAPERLESS_API_URL")
86+
or os.getenv("PAPERLESS_URL")
87+
or os.getenv("PAPERLESS_NGX_URL")
88+
or os.getenv("PAPERLESS_HOST")
89+
)
90+
paperless_token = os.getenv("PAPERLESS_TOKEN") or os.getenv("PAPERLESS_API_TOKEN") or os.getenv("PAPERLESS_APIKEY")
91+
92+
if paperless_api_url:
93+
paperless_api_url = paperless_api_url.strip()
94+
if paperless_api_url.endswith('/api'):
95+
paperless_api_url = paperless_api_url[:-4]
96+
logger.info(f"Removed '/api' suffix from URL: {paperless_api_url}")
97+
98+
if paperless_token:
99+
paperless_token = paperless_token.strip()
100+
101+
if _is_missing_or_placeholder(paperless_api_url):
102+
paperless_api_url = None
103+
104+
if _is_missing_or_placeholder(paperless_token):
105+
paperless_token = None
106+
107+
return paperless_api_url, paperless_token
108+
57109
# Constants
58110
DOCUMENTS_FILE = "./data/documents.json"
59111
CHROMADB_DIR = "./data/chromadb"
@@ -213,16 +265,8 @@ def load_state(self):
213265
# Data Manager
214266
class DataManager:
215267
def __init__(self, initialize_on_start=False):
216-
# Flexible Variablennamen für die API-Einstellungen - erweitert um PAPERLESS_API_URL
217-
paperless_api_url = os.getenv("PAPERLESS_API_URL") or os.getenv("PAPERLESS_URL") or os.getenv("PAPERLESS_NGX_URL") or os.getenv("PAPERLESS_HOST")
218-
219-
# Entfernen des /api Suffix falls vorhanden
220-
if paperless_api_url and paperless_api_url.endswith('/api'):
221-
paperless_api_url = paperless_api_url[:-4] # Entfernen der letzten 4 Zeichen (/api)
222-
logger.info(f"Removed '/api' suffix from URL: {paperless_api_url}")
223-
224-
self.paperless_url = paperless_api_url
225-
self.paperless_token = os.getenv("PAPERLESS_TOKEN") or os.getenv("PAPERLESS_API_TOKEN") or os.getenv("PAPERLESS_APIKEY")
268+
# Resolve and validate env aliases once so startup can reliably detect invalid config.
269+
self.paperless_url, self.paperless_token = _resolve_paperless_config()
226270

227271
# Debug-Informationen ausgeben
228272
logger.info(f"Environment variables: PAPERLESS_API_URL={os.getenv('PAPERLESS_API_URL')}, PAPERLESS_URL={os.getenv('PAPERLESS_URL')}, PAPERLESS_NGX_URL={os.getenv('PAPERLESS_NGX_URL')}, PAPERLESS_HOST={os.getenv('PAPERLESS_HOST')}")
@@ -1549,6 +1593,15 @@ async def startup_event():
15491593
global_state.save_state()
15501594
return
15511595

1596+
paperless_url, paperless_token = _resolve_paperless_config()
1597+
if not paperless_url or not paperless_token:
1598+
logger.warning("Paperless API configuration missing or contains placeholder values")
1599+
logger.warning("Starting with limited functionality due to missing API configuration")
1600+
global_state.system_status.server_up = True
1601+
global_state.indexing_status.message = "API configuration missing or invalid in data/.env"
1602+
global_state.save_state()
1603+
return
1604+
15521605
# Initialize DataManager without model loading to keep API responsive
15531606
global_state.data_manager = DataManager(initialize_on_start=False)
15541607
global_state.indexing_status.message = "Waiting for initialization"
@@ -1698,12 +1751,16 @@ def post_startup_init_work():
16981751
global_state.indexing_status.message = f"Error during startup: {str(e)}"
16991752
global_state.save_state()
17001753

1701-
# Even if there's an error, try to initialize basic components
1702-
if not global_state.data_manager:
1754+
# Even if there's an error, try to initialize basic components when config is valid.
1755+
paperless_url, paperless_token = _resolve_paperless_config()
1756+
1757+
if not global_state.data_manager and paperless_url and paperless_token:
17031758
try:
17041759
global_state.data_manager = DataManager(initialize_on_start=False)
17051760
except Exception as dm_error:
17061761
logger.error(f"Failed to initialize DataManager: {str(dm_error)}")
1762+
elif not paperless_url or not paperless_token:
1763+
logger.warning("Skipping DataManager initialization because API configuration is missing or invalid")
17071764

17081765
if not global_state.search_engine and global_state.data_manager:
17091766
try:

0 commit comments

Comments
 (0)