{"id":976,"library":"cron-descriptor","title":"Cron Descriptor","description":"A Python library that converts cron expressions into human readable strings. As of version 2.0.8, it supports Python 3.9 - 3.14 and offers localization for approximately 31 languages. The library is actively maintained with frequent releases.","status":"active","version":"2.0.8","language":"python","source_language":"en","source_url":"https://github.com/Salamek/cron-descriptor","tags":["cron","scheduling","human-readable","parser","localization"],"install":[{"cmd":"pip install cron-descriptor","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python >=3.9","package":"python","optional":false}],"imports":[{"note":"Direct import from the top-level package is the current standard. Older versions might have had deeper imports, or some examples might mistakenly show a submodule.","wrong":"from cron_descriptor.ExpressionDescriptor import get_description","symbol":"get_description","correct":"from cron_descriptor import get_description"},{"symbol":"ExpressionDescriptor","correct":"from cron_descriptor import ExpressionDescriptor"},{"symbol":"Options","correct":"from cron_descriptor import Options"},{"symbol":"CasingTypeEnum","correct":"from cron_descriptor import CasingTypeEnum"},{"symbol":"DescriptionTypeEnum","correct":"from cron_descriptor import DescriptionTypeEnum"}],"quickstart":{"code":"from cron_descriptor import get_description, ExpressionDescriptor, Options, CasingTypeEnum, DescriptionTypeEnum\n\n# Simple usage\nprint(get_description(\"* 2 3 * *\"))\n\n# Using ExpressionDescriptor class\ndescriptor_instance = ExpressionDescriptor(\"* 2 3 * *\")\nprint(str(descriptor_instance))\n\n# Advanced usage with Options\noptions = Options()\noptions.casing_type = CasingTypeEnum.Sentence\noptions.use_24hour_time_format = True\noptions.locale_code = 'en' # Explicitly set locale for consistency\n\nadvanced_descriptor = ExpressionDescriptor(\"*/10 * * * *\", options)\nprint(advanced_descriptor.get_description(DescriptionTypeEnum.FULL))\n","lang":"python","description":"Demonstrates basic usage with the `get_description` function and the `ExpressionDescriptor` class, including how to customize output with `Options` for casing, 24-hour format, and locale."},"warnings":[{"fix":"Wrap `ExpressionDescriptor()` instantiation in a `try...except` block to catch parsing errors.","message":"The parsing of cron expressions moved from `ExpressionDescriptor.get_description()` to the `ExpressionDescriptor` constructor in version 1.3. This means parsing exceptions are now thrown when creating an `ExpressionDescriptor` instance, not when calling `get_description()`. Update your exception handling logic accordingly.","severity":"breaking","affected_versions":"<=1.2.x to >=1.3"},{"fix":"Ensure all cron expressions passed to the descriptor are valid, or implement `try...except` blocks around `ExpressionDescriptor` instantiation.","message":"The `throw_exception_on_parse_error` option was removed in version 1.3. The library now always throws an exception if a cron expression cannot be parsed, effectively behaving as if `throw_exception_on_parse_error=True`.","severity":"breaking","affected_versions":"<=1.2.x to >=1.3"},{"fix":"Review `Options` constructor usage to ensure desired locale and time format behavior. Explicitly set `locale_code` if you need a specific localization, or omit it to rely on auto-detection.","message":"In version 2.0.3, the `Options` constructor parameters (`locale_code`, `use_24hour_time_format`) now explicitly override auto-detected system locale settings. If you previously relied on auto-detection and then set these in `Options` objects, their behavior might change to reflect the explicit settings.","severity":"breaking","affected_versions":"<=2.0.2 to >=2.0.3"},{"fix":"Update `except` blocks to catch the new exception names (e.g., `CronDescriptorError` instead of `CronDescriptorException`). Consult the source for specific exception names if needed.","message":"Custom exceptions within the library were renamed from `*Exception` (e.g., `CronDescriptorException`) to `*Error` (e.g., `CronDescriptorError`) in version 2.0.3. Update `except` clauses to catch the new exception names.","severity":"breaking","affected_versions":"<=2.0.2 to >=2.0.3"},{"fix":"Use `?` in either the Day of Month or Day of Week field if you intend for one to be ignored. For example, `0 0 1 * ?` (1st of every month, any day of week) or `0 0 ? * MON` (every Monday, any day of month).","message":"Using both Day of Month and Day of Week fields with explicit values (e.g., `1 1 1 1 1`) can be ambiguous in cron. While this library generally handles `?` to signify 'no specific value' for one of them, be aware that other cron parsers or environments might have different interpretations or stricter validation.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T22:03:45.393Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install cron-descriptor`","cause":"The 'cron-descriptor' library is not installed in your Python environment or the environment where the script is being executed.","error":"ModuleNotFoundError: No module named 'cron_descriptor'"},{"fix":"Review and correct the cron expression string to adhere to standard cron syntax. Ensure it's a valid 5, 6 (with seconds or year), or 7 part cron expression.","cause":"The provided cron expression string is syntactically incorrect or contains unsupported patterns, causing the library to fail during parsing.","error":"cron_descriptor.Exception.FormatError: An error occurred when generating the expression description. Check the cron expression syntax."},{"fix":"Verify the correct name and source of the component you intend to import. Common imports are `get_description`, `ExpressionDescriptor`, `Options`, `CasingTypeEnum`, and `DescriptionTypeEnum`.","cause":"You are attempting to import a class, function, or variable name that does not exist or is not directly exposed by the 'cron_descriptor' module.","error":"ImportError: cannot import name 'NonExistentClass' from 'cron_descriptor' (or similar for other names)"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.0.8","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":3.2,"disk_size":"18.4M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":3.2,"disk_size":"18.4M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.04,"mem_mb":3.2,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":3.2,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3.6,"disk_size":"20.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":3.6,"disk_size":"20.4M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.11,"mem_mb":3.6,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":3.6,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":3.5,"disk_size":"12.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":3.5,"disk_size":"12.2M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.11,"mem_mb":3.5,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":3.5,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":3.6,"disk_size":"12.0M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":3.6,"disk_size":"11.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.09,"mem_mb":3.6,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":3.6,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":3.2,"disk_size":"17.9M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":3.2,"disk_size":"17.9M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.8,"import_time_s":0.05,"mem_mb":3.2,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":3.2,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}