Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ds_format_locale method in macros which allows localizing datetime formatting using Babel #40746

Merged
merged 30 commits into from
Jul 17, 2024

Conversation

dabla
Copy link
Contributor

@dabla dabla commented Jul 12, 2024

Added optional locale parameter to the ds_format method in macros to be able to specify a locale so datetimes can be formatted with the corresponding language.

For example following:

ds_format('05', '%m', '%b', 'en_US')
> 'May'
ds_format('05', '%m', '%b', 'nl_BE') 
> 'mei'
ds_format('12/07/2024', '%d/%m/%Y', '%A %d %B %Y', 'en_US')
> 'Friday 12 July 2024'
ds_format('12/07/2024', '%d/%m/%Y', '%A %d %B %Y', 'nl_BE')
> 'vrijdag 12 juli 2024'

This can be very handy in jinja expressions where you need for example specifiy different formatting for multiple languages.


^ Add meaningful description above
Read the Pull Request Guidelines for more information.
In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed.
In case of a new dependency, check compliance with the ASF 3rd Party License Policy.
In case of backwards incompatible changes please leave a note in a newsfragment file, named {pr_number}.significant.rst or {issue_number}.significant.rst, in newsfragments.

@potiuk
Copy link
Member

potiuk commented Jul 12, 2024

Just be aware that you will only be able to use for Airflow 2.10+ - I think it would be nice to add .. versionadded:: 2.10.0 somewher in the docsstring

@potiuk
Copy link
Member

potiuk commented Jul 12, 2024

Also maybe worth to add a compat version to providers/common/compat

@potiuk
Copy link
Member

potiuk commented Jul 12, 2024

Also maybe worth to add a compat version to providers/common/compat

That would be the first thing added.

@dabla
Copy link
Contributor Author

dabla commented Jul 12, 2024

Also maybe worth to add a compat version to providers/common/compat

That would be the first thing added.

Thank you Jarek for the tips will do that.

@dabla
Copy link
Contributor Author

dabla commented Jul 13, 2024

Also maybe worth to add a compat version to providers/common/compat

What do I have to put there, as the macros is part of Airflow itself and is not in the providers? Docstring is updated as you suggested.

@uranusjr
Copy link
Member

I don’t like how this modifies the locale globally (albeit in a context manager). This tend to lead to bugs in concurrent situations. Is it possible to use Babel for this? We already have the package as a trasitive dependency (for various web packages).

https://babel.pocoo.org/en/latest/api/dates.html

@dabla
Copy link
Contributor Author

dabla commented Jul 15, 2024

I don’t like how this modifies the locale globally (albeit in a context manager). This tend to lead to bugs in concurrent situations. Is it possible to use Babel for this? We already have the package as a trasitive dependency (for various web packages).

https://babel.pocoo.org/en/latest/api/dates.html

I've tried that. The problem with that is that it uses another formatting syntax, which made unit tests fail and which would be confusing and a breaking chang of that method.

@uranusjr
Copy link
Member

it uses another formatting syntax

Sign. Let me dig around for alternatives…

@uranusjr
Copy link
Member

Apparently there’s not, Python’s API is just a very thin wrapper around the C implementation, and the C API can only use the current locale. Very bad but what can you expect from something designed 40 years ago. I guess a context manager is the best we can do for now—if bad things happen down the road we’ll add a lock to work around it.

@dabla
Copy link
Contributor Author

dabla commented Jul 15, 2024

Apparently there’s not, Python’s API is just a very thin wrapper around the C implementation, and the C API can only use the current locale. Very bad but what can you expect from something designed 40 years ago. I guess a context manager is the best we can do for now—if bad things happen down the road we’ll add a lock to work around it.

This also works, and that's converting the python datetime format to babel:

def ds_format(ds: str, input_format: str, output_format: str, locale: str | None = None) -> str:
    def strftime_to_babel_format(format_str):
        # Mapping of strftime format codes to Babel format codes
        format_mapping = {
            '%a': 'EEE', '%A': 'EEEE', '%w': 'e', '%d': 'dd', '%b': 'MMM', '%B': 'MMMM', '%m': 'MM',
            '%y': 'yy', '%Y': 'yyyy', '%H': 'HH', '%I': 'hh', '%p': 'a', '%M': 'mm', '%S': 'ss',
            '%f': 'SSSSSS', '%z': 'Z', '%Z': 'z', '%j': 'D', '%U': 'w', '%W': 'w',
            '%c': 'EEE MMM dd HH:mm:ss yyyy',
            '%x': 'MM/dd/yy', '%X': 'HH:mm:ss', '%%': '%'
        }

        for k, v in format_mapping.items():
            format_str = format_str.replace(k, v)

        return format_str

    """
    Output datetime string in a given format.

    :param ds: Input string which contains a date.
    :param input_format: Input string format (e.g., '%Y-%m-%d').
    :param output_format: Output string format (e.g., '%Y-%m-%d').
    :param locale: Locale used to format the output string (e.g., 'en_US').
                   If None (default), the locale will not be changed.

    >>> ds_format("2015-01-01", "%Y-%m-%d", "%m-%d-%y")
    '01-01-15'
    >>> ds_format("1/5/2015", "%m/%d/%Y", "%Y-%m-%d")
    '2015-01-05'
    >>> ds_format("12/07/2024", "%d/%m/%Y", "%A %d %B %Y", "en_US")
    'Friday 12 July 2024'

    .. versionadded:: 2.10.0
       The `locale` parameter.
    """
    date_obj = datetime.strptime(str(ds), input_format)
    if locale:
        return format_datetime(date_obj, format=strftime_to_babel_format(output_format), locale=locale)
    return date_obj.strftime(output_format)

@uranusjr
Copy link
Member

There are likely edge cases though (I didn’t check but it’s very likely). Let’s not try too hard on this.

@dabla
Copy link
Contributor Author

dabla commented Jul 15, 2024

There are likely edge cases though (I didn’t check but it’s very likely). Let’s not try too hard on this.

Yes but if you are worried of potential side-effects even when using a context manager, and I wasn't aware of this as I'm not that long in Pyhton, then I would opt for the later solution. And yes maybe there will be edge cases, BUT, at least it will be safe AND it's a new funcitonality, which means that if you don't pass the locale as argument, you're still using the original solution. If something would fail in combination wiht the locale, we can always fix it. All test cases are good with above solution, I would personally prefer this one over a hackish solution with context manager, wasn't happy about it in the first place so it's a good thing you pointed this out! ;)

@dabla
Copy link
Contributor Author

dabla commented Jul 15, 2024

There are likely edge cases though (I didn’t check but it’s very likely). Let’s not try too hard on this.

Or we add a new macro method ds_format_babel or ds_format_locale and specify there you have to use the babel format?

@uranusjr
Copy link
Member

I think adding a new macro based on Babel is a good idea! Not sure about the name but I like it otherwise.

@dabla dabla changed the title Added optional locale parameter to the ds_format method in macros Added ds_format_locale method in macros which allows localizing datetime formatting wiht Babel Jul 15, 2024
@dabla dabla changed the title Added ds_format_locale method in macros which allows localizing datetime formatting wiht Babel Added ds_format_locale method in macros which allows localizing datetime formatting using Babel Jul 15, 2024
@potiuk potiuk merged commit 6058014 into apache:main Jul 17, 2024
48 checks passed
@ephraimbuddy ephraimbuddy added type:improvement Changelog: Improvements type:new-feature Changelog: New Features and removed type:improvement Changelog: Improvements labels Jul 22, 2024
@ephraimbuddy ephraimbuddy added this to the Airflow 2.10.0 milestone Jul 23, 2024
romsharon98 pushed a commit to romsharon98/airflow that referenced this pull request Jul 26, 2024
…ime formatting using Babel (apache#40746)



---------

Co-authored-by: David Blain <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:new-feature Changelog: New Features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants