diff --git a/README.md b/README.md index 12287a2..da2223e 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Optional ├── country_indeed (enum): filters the country on Indeed (see below for correct spelling) ├── offset (num): starts the search from an offset (e.g. 25 will start the search from the 25th result) ├── hours_old (int): filters jobs by the number of hours since the job was posted (ZipRecruiter and Glassdoor round up to next day. If you use this on Indeed, it will not filter by job_type or is_remote) +├── verbose (int) {0, 1, 2}: Controls the verbosity of the runtime printouts (0 prints only errors, 1 is errors+warnings, 2 is all logs. Default is 2.) ``` ### JobPost Schema diff --git a/src/jobspy/__init__.py b/src/jobspy/__init__.py index 07b5b27..0f7fbb2 100644 --- a/src/jobspy/__init__.py +++ b/src/jobspy/__init__.py @@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed from .jobs import JobType, Location -from .scrapers.utils import logger +from .scrapers.utils import logger, set_logger_level from .scrapers.indeed import IndeedScraper from .scrapers.ziprecruiter import ZipRecruiterScraper from .scrapers.glassdoor import GlassdoorScraper @@ -36,6 +36,7 @@ def scrape_jobs( linkedin_company_ids: list[int] | None = None, offset: int | None = 0, hours_old: int = None, + verbose: int = 2, **kwargs, ) -> pd.DataFrame: """ @@ -48,6 +49,7 @@ def scrape_jobs( Site.ZIP_RECRUITER: ZipRecruiterScraper, Site.GLASSDOOR: GlassdoorScraper, } + set_logger_level(verbose) def map_str_to_site(site_name: str) -> Site: return Site[site_name.upper()] diff --git a/src/jobspy/scrapers/utils.py b/src/jobspy/scrapers/utils.py index 844cf8b..8fef421 100644 --- a/src/jobspy/scrapers/utils.py +++ b/src/jobspy/scrapers/utils.py @@ -21,6 +21,23 @@ logger.addHandler(console_handler) +def set_logger_level(verbose: int = 2): + """ + Adjusts the logger's level. This function allows the logging level to be changed at runtime. + + Parameters: + - verbose: int {0, 1, 2} (default=2, all logs) + """ + if verbose is None: + return + level_name = {2: "INFO", 1: "WARNING", 0: "ERROR"}.get(verbose, "INFO") + level = getattr(logging, level_name.upper(), None) + if level is not None: + logger.setLevel(level) + else: + raise ValueError(f"Invalid log level: {level_name}") + + def markdown_converter(description_html: str): if description_html is None: return None