Skip to content

Commit d3ead97

Browse files
committed
logging PR
Signed-off-by: Miguel Brandão <[email protected]>
1 parent aaf0d10 commit d3ead97

File tree

16 files changed

+235
-7
lines changed

16 files changed

+235
-7
lines changed

deepsearch/artifacts/artifact_manager.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import logging
2+
3+
logger = logging.getLogger("root.artifacts")
4+
15
import json
26
import os
37
import shutil
@@ -40,6 +44,7 @@ def get_index_path(self) -> Path:
4044
def get_artifact_path_in_cache(self, artifact_name: str) -> Path:
4145
artifact_path = self._cache_path / artifact_name
4246
if not artifact_path.exists():
47+
logger.error(f'Artifact "{artifact_name}" not in cache')
4348
raise FileNotFoundError(f'Artifact "{artifact_name}" not in cache')
4449
return artifact_path
4550

@@ -52,13 +57,18 @@ def download_artifact_to_cache(
5257
) -> None:
5358
artifact_path = self._cache_path / artifact_name
5459
if artifact_path.exists():
60+
logger.info(f"Artifact already in cache using {hit_strategy=}")
5561
if hit_strategy == self.HitStrategy.RAISE:
62+
logger.error(f'Artifact "{artifact_name}" already in cache')
5663
raise ValueError(f'Artifact "{artifact_name}" already in cache')
5764
elif hit_strategy == self.HitStrategy.PASS:
65+
logger.info(f"Skipped artifact")
5866
return
5967
elif hit_strategy == self.HitStrategy.OVERWRITE:
68+
logger.info(f"Overwriting artifact")
6069
shutil.rmtree(artifact_path)
6170
else:
71+
logger.error(f'Unexcpected value "{hit_strategy=}"')
6272
raise RuntimeError(f'Unexcpected value "{hit_strategy=}"')
6373

6474
artifact_path.mkdir(exist_ok=False)
@@ -70,6 +80,7 @@ def download_artifact_to_cache(
7080
download_url = artifact_meta[ARTF_META_URL_FIELD]
7181

7282
with tempfile.TemporaryDirectory() as temp_dir:
83+
logger.info("Downloading artifact to temporary directory")
7384
download_path = self._download_file(
7485
artifact_name=artifact_name,
7586
download_url=download_url,
@@ -108,6 +119,7 @@ def _download_file(
108119
with_progress_bar: bool,
109120
) -> Path:
110121
response = requests.get(download_url, stream=True)
122+
logger.info(f"{response.status_code} response from {download_url}")
111123
response.raise_for_status()
112124

113125
dl_filename = None
@@ -123,10 +135,13 @@ def _download_file(
123135
dl_filename = "=".join(split_param[1:]).strip().strip("'\"")
124136
break
125137

126-
# otherwise, use name from URL:
127-
if dl_filename is None:
138+
if dl_filename:
139+
logger.info(f"Resolved filename from response header {dl_filename}")
140+
else:
141+
# otherwise, use name from URL:
128142
parsed_url = urlparse(download_url)
129143
dl_filename = Path(parsed_url.path).name
144+
logger.info(f"Resolved filename from url {dl_filename}")
130145

131146
total_size = int(response.headers.get("content-length", 0))
132147
block_size = 1024 # 1 KB
@@ -168,13 +183,16 @@ def _finalize_download(
168183
attempt_unpack = True
169184

170185
if attempt_unpack:
186+
logger.info("Unpacking archive and moving to destination")
171187
shutil.unpack_archive(dl_path_str, target_path)
172188
else:
189+
logger.info("Moving archive to destination")
173190
shutil.move(dl_path_str, target_path / "")
174191

175192
def _get_artifact_meta(self, artifact_name: str) -> Dict:
176193
file_path = self._index_path / artifact_name / ARTF_META_FILENAME
177194
if not file_path.exists():
195+
logger.error(f'File "{file_path}" does not exist')
178196
raise FileNotFoundError(f'File "{file_path}" does not exist')
179197
with open(file_path, "r") as file:
180198
meta_info = json.load(file)

deepsearch/artifacts/cli/main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import logging
2+
3+
logger = logging.getLogger("root.artifacts")
14
import typer
25

36
from deepsearch.artifacts.artifact_manager import (
@@ -36,6 +39,7 @@
3639
def list_index(
3740
index: str = INDEX_OPTION,
3841
):
42+
logger.info("Listing artifacts in index")
3943
artf_mgr = ArtifactManager(index=index)
4044
artifacts = artf_mgr.get_artifacts_in_index()
4145
for artf in artifacts:
@@ -47,6 +51,7 @@ def list_index(
4751
def list_cache(
4852
cache: str = CACHE_OPTION,
4953
):
54+
logger.info("Listing artifacts in cache")
5055
artf_mgr = ArtifactManager(cache=cache)
5156
artifacts = artf_mgr.get_artifacts_in_cache()
5257
for artf in artifacts:
@@ -56,6 +61,7 @@ def list_cache(
5661
@app.command(help="Show cache path")
5762
@cli_handler()
5863
def locate_default_cache():
64+
logger.info("Resolving cache path")
5965
artf_mgr = ArtifactManager()
6066
path_str = str(artf_mgr.get_cache_path().resolve())
6167
typer.echo(path_str)
@@ -83,6 +89,7 @@ def download(
8389
unpack: bool = typer.Option(True),
8490
progress_bar: bool = typer.Option(True),
8591
):
92+
logger.info(f"Attempting to download {artifact_name=} from {index=}")
8693
artf_mgr = ArtifactManager(index=index, cache=cache)
8794
artf_mgr.download_artifact_to_cache(
8895
artifact_name=artifact_name,
@@ -101,6 +108,7 @@ def download_all(
101108
unpack: bool = typer.Option(True),
102109
progress_bar: bool = typer.Option(True),
103110
):
111+
logger.info(f"Attempting to download all artifacts from {index=}")
104112
artf_mgr = ArtifactManager(index=index, cache=cache)
105113
for artf_name in artf_mgr.get_artifacts_in_index():
106114
artf_mgr.download_artifact_to_cache(

deepsearch/cli.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,67 @@
1+
import logging
2+
from pathlib import Path
3+
from typing import List
4+
5+
from deepsearch import DeepSearchConfig
16
from deepsearch.artifacts.cli.main import app as artifacts_app
27
from deepsearch.core.cli.main import app
38
from deepsearch.core.cli.plugins import get_cli_groups
9+
from deepsearch.core.util.config_paths import config_file_path
410
from deepsearch.cps.cli.main import app as cps_app
511
from deepsearch.documents.cli.main import app as documents_app
612
from deepsearch.query.cli.main import app as query_app
713

14+
# TODO review if unwanted information is being logged
15+
16+
17+
def setup_logger():
18+
# Setting up root logger
19+
config_file = config_file_path()
20+
21+
if not config_file.exists():
22+
raise RuntimeError(
23+
f"Config file {config_file} does not exist. Please configure your default authentication with `$ deepsearch login`"
24+
)
25+
config = DeepSearchConfig.parse_file(config_file)
26+
27+
p = Path(config.log_configuration.target_file)
28+
if not p.parent.is_dir():
29+
p.parent.mkdir(parents=True)
30+
31+
handlers: List[logging.Handler] = [
32+
logging.FileHandler(p),
33+
]
34+
if config.log_configuration.write_to_console:
35+
handlers.append(logging.StreamHandler())
36+
formatter = logging.Formatter(
37+
"%(asctime)s %(name)s — %(levelname)s — %(module)s:%(funcName)s:%(lineno)d — %(message)s"
38+
)
39+
logger = logging.getLogger("root")
40+
[h.setFormatter(formatter) for h in handlers] # type: ignore
41+
[logger.addHandler(h) for h in handlers] # type: ignore
42+
[e.setLevel(logging.DEBUG) for e in (logger, *handlers)] # type: ignore
43+
44+
return logger
45+
46+
47+
logger = setup_logger()
48+
849
app.add_typer(cps_app, name="cps", help="Interact with DeepSearch CPS component")
50+
logger.info("Cps module initialized")
951
app.add_typer(query_app, name="query", help="Interact with DeepSearch Query component")
52+
logger.info("Query module initialized")
1053
app.add_typer(
1154
documents_app,
1255
name="documents",
1356
help="Interact with DeepSearch Document Conversion component",
1457
)
58+
logger.info("Documents module initialized")
1559
app.add_typer(artifacts_app, name="artifacts", help="Manage artifacts")
60+
logger.info("Artifacts module initialized")
1661

1762
for group in get_cli_groups():
1863
app.add_typer(group)
19-
64+
logger.info("Root module finished initialization")
2065

2166
if __name__ == "__main__":
2267
app()

deepsearch/core/cli/main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import logging
2+
3+
logger = logging.getLogger("root.core")
4+
5+
16
import typer
27

38
import deepsearch as ds
@@ -13,10 +18,11 @@
1318
)
1419
app.add_typer(profile_app, name="profile", help="Manage profile configuration")
1520
app.add_typer(login_app, name="login", help=MSG_LOGIN_DEPRECATION)
16-
21+
logger.info("Core module finished initialization")
1722

1823
@app.command(name="version", help=f"Print the client and server version")
1924
def get_version():
25+
logger.info("Getting DeepSearch version")
2026
versions = ds.version()
2127
typer.echo(f"Client: {versions.client}")
2228
typer.echo(f"Server: {versions.server}")

deepsearch/core/cli/plugins.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import logging
12
from typing import List
23

4+
logger = logging.getLogger("root.core.plugins")
5+
36
import pluggy
47
import typer
58

69
deepsearch_cli_hookspec = pluggy.HookspecMarker("deepsearch_cli")
710
deepsearch_cli_hookimpl = pluggy.HookimplMarker("deepsearch_cli")
811

12+
logger.info("Plugins module initialized")
13+
914

1015
class DeepsearchCliPlugin:
1116
@deepsearch_cli_hookspec
@@ -15,10 +20,12 @@ def deepsearch_cli_add_group(self) -> typer.Typer:
1520
1621
:return: A typer.Typer instance with a name set.
1722
"""
23+
logger.error("Feature not implemented")
1824
raise NotImplementedError
1925

2026

2127
def get_cli_plugin_manager():
28+
logger.info("getting cli plugin manager")
2229
manager = pluggy.PluginManager("deepsearch_cli")
2330

2431
manager.add_hookspecs(DeepsearchCliPlugin)
@@ -34,6 +41,7 @@ def get_cli_groups() -> List[typer.Typer]:
3441

3542
for app in apps:
3643
if not app.info.name:
44+
logger.error(f"All registered apps must have names, but {app} doesn't")
3745
raise ValueError(f"All registered apps must have names, but {app} doesn't")
3846

3947
return apps

deepsearch/core/client/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from typing import Union
22

3+
from platformdirs import user_log_dir
34
from pydantic import BaseModel
45

56

@@ -15,7 +16,13 @@ class DeepSearchKeyAuth(BaseModel):
1516
DeepSearchAuth = Union[DeepSearchBearerTokenAuth, DeepSearchKeyAuth]
1617

1718

19+
class DeepSearchLogConfig(BaseModel):
20+
target_file: str = user_log_dir("DeepSearch", "IBM")
21+
write_to_console: bool = False
22+
23+
1824
class DeepSearchConfig(BaseModel):
1925
host: str
2026
auth: DeepSearchAuth
2127
verify_ssl: bool = True
28+
log_configuration: DeepSearchLogConfig

deepsearch/cps/cli/data_indices_typer.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import logging
2+
3+
logger = logging.getLogger("root.cps.data_indices")
4+
15
from enum import Enum
26
from pathlib import Path
37
from typing import List
@@ -38,6 +42,7 @@ def list(
3842
output: OutputEnum = OutputOption,
3943
):
4044
api = CpsApi.from_env()
45+
logger.info(f"Listing data indices in project {proj_key}")
4146

4247
try:
4348
indices = api.data_indices.list(proj_key=proj_key)
@@ -52,6 +57,7 @@ def list(
5257
for index in indices
5358
]
5459
except ValueError as e:
60+
logger.error(e)
5561
print(f"Error occurred: {e}")
5662

5763
cli_output(results, output, headers="keys")
@@ -72,6 +78,7 @@ def create(
7278
),
7379
):
7480
api = CpsApi.from_env()
81+
logger.info(f"Create data index in project {proj_key}, {name=}, {desc=}, {type=}")
7582

7683
try:
7784
api.data_indices.create(
@@ -82,6 +89,7 @@ def create(
8289
)
8390
typer.echo("Data Index Created.")
8491
except ValueError as e:
92+
logger.error(e)
8593
typer.echo(f"Error occurred: {e}")
8694
typer.echo(ERROR_MSG)
8795
raise typer.Abort()
@@ -95,19 +103,23 @@ def delete_data_index(
95103
index_key: str = INDEX_KEY,
96104
):
97105
api = CpsApi.from_env()
106+
logger.info(f"Deleting data index from project {proj_key}, {index_key=}")
98107
delete = typer.confirm("Are you sure you want to delete this data index?")
99108

100109
coords = ElasticProjectDataCollectionSource(proj_key=proj_key, index_key=index_key)
101110

102111
if not delete:
103112
typer.echo("Cancelling delete operation.")
113+
logger.info("Cancelling delete operation.")
104114
raise typer.Abort()
105115
elif delete:
106116
# get confirmation token
107117
try:
108118
api.data_indices.delete(coords)
109119
typer.echo("Deleted!")
120+
logger.info("Index deleted")
110121
except ApiException as e:
122+
logger.error(e)
111123
typer.echo(f"Error occurred: {e}")
112124
typer.echo(ERROR_MSG)
113125
raise typer.Abort()
@@ -118,7 +130,7 @@ def get_urls(path: Path) -> List[str]:
118130
"""
119131
Returns list of url from input file.
120132
"""
121-
133+
logger.info(f"Getting url list from {path}")
122134
lines = path.read_text()
123135
urls = [line.strip() for line in lines.split("\n") if line.strip() != ""]
124136
return urls
@@ -136,12 +148,17 @@ def upload_files(
136148
Upload pdfs, zips, or online documents to a data index in a project
137149
"""
138150

151+
logger.info(
152+
f"Uploading files/urls to {proj_key=} in {index_key=}. {url=} {local_file=}"
153+
)
139154
urls = None
140155
if url is not None:
141156
p = Path(url)
142157
urls = get_urls(p) if p.exists() else [url]
143158

144159
coords = ElasticProjectDataCollectionSource(proj_key=proj_key, index_key=index_key)
160+
# TODO this looks bugged ? urls is never used only the unprocessed url
161+
logger.info(f"Uploading to {coords=}")
145162
utils.upload_files(coords=coords, url=url, local_file=local_file)
146163
return
147164

@@ -161,6 +178,9 @@ def add_attachment(
161178
Add attachment to a index item
162179
"""
163180
api = CpsApi.from_env()
181+
logger.info(
182+
f"Adding attachment to index item {proj_key=} {index_key=}, {index_item_id=}, {attachment_key=} {attachment_path=}"
183+
)
164184

165185
# get indices of the project
166186
indices = api.data_indices.list(proj_key)
@@ -176,13 +196,16 @@ def add_attachment(
176196
attachment_path=attachment_path,
177197
attachment_key=attachment_key,
178198
)
199+
logger.info(f"Attachment added successfully.")
179200
typer.echo("Attachment added successfully.")
180201
except ValueError as e:
202+
logger.error(e)
181203
typer.echo(f"Error occurred: {e}")
182204
typer.echo(ERROR_MSG)
183205
raise typer.Abort()
184206
return
185207
else:
208+
logger.info("Index key not found")
186209
typer.echo("Index key not found")
187210
raise typer.Abort()
188211

0 commit comments

Comments
 (0)