Skip to content

Parser

Date and path parsing utilities used throughout ProgridPy. Provides flexible date parsing that accepts multiple string formats (YYYYMMDD, YYYY-MM-DD, YYYY/MM/DD), datetime.date, datetime.datetime, and None (defaults to today in the given timezone).

Key Functions

  • parse_datetime -- Parses a date value into a timezone-aware datetime. Accepts strings, date, datetime, or None.
  • parse_file_location -- Converts a string to a FileLocation enum member.
  • ensure_output_file / to_path -- Path normalization and parent-directory creation helpers.

Functions

parse_datetime

parse_datetime(value: str | date | datetime | None, tz: str | tzinfo = 'UTC') -> datetime

Parse datetime in various formats: YYYYMMDD, YYYY/MM/DD, YYYY-MM-DD.

Arguments: value (str | date | datetime | None): Date to parse tz (str | tzinfo): Timezone name or tzinfo instance

Returns: datetime: Parsed datetime object

Raises: ValueError: If the date format is not supported

Source code in src/progridpy/utils/parser.py
def parse_datetime(value: str | date | datetime | None, tz: str | tzinfo = "UTC") -> datetime:
    """
    Parse datetime in various formats: YYYYMMDD, YYYY/MM/DD, YYYY-MM-DD.

    Arguments:
        value (str | date | datetime | None): Date to parse
        tz (str | tzinfo): Timezone name or tzinfo instance

    Returns:
        datetime: Parsed datetime object

    Raises:
        ValueError: If the date format is not supported
    """
    if isinstance(tz, str):
        tz = zoneinfo.ZoneInfo(tz)

    if value is None:
        today = datetime.now(tz=tz)
        return today.replace(hour=0, minute=0, second=0, microsecond=0)

    if isinstance(value, datetime):
        return value.replace(tzinfo=tz)

    if isinstance(value, date):
        return datetime(value.year, value.month, value.day, tzinfo=tz)

    date_str = value.strip()

    # Try different formats
    formats = [
        "%Y%m%d",  # YYYYMMDD
        "%Y/%m/%d",  # YYYY/MM/DD
        "%Y-%m-%d",  # YYYY-MM-DD
    ]

    for fmt in formats:
        try:
            return datetime.strptime(date_str, fmt).replace(tzinfo=tz)
        except ValueError:
            continue

    raise ValueError(f"Unsupported date format: {date_str}. Supported formats are: YYYYMMDD, YYYY/MM/DD, YYYY-MM-DD")

parse_file_location

parse_file_location(location_str: str) -> FileLocation

Parse file location string to FileLocation enum.

Arguments: location_str (str): Location string to parse

Returns: FileLocation: Parsed FileLocation enum

Raises: ValueError: If the location string is not supported

Source code in src/progridpy/utils/parser.py
def parse_file_location(location_str: str) -> FileLocation:
    """
    Parse file location string to FileLocation enum.

    Arguments:
        location_str (str): Location string to parse

    Returns:
        FileLocation: Parsed FileLocation enum

    Raises:
        ValueError: If the location string is not supported
    """
    location_str = location_str.strip().lower()

    if location_str == "s3":
        return FileLocation.S3
    if location_str == "iso":
        return FileLocation.ISO
    raise ValueError(f"Unsupported download source: {location_str}. Supported values are: 's3', 'iso'")