1+ from contextlib import suppress
12from typing import Any , Final
23
4+ from packaging .version import Version
5+
6+ from ..._meta import API_VERSION
7+
38#
49# CHANGELOG formatted-messages for API routes
510#
1520# changes in given version with message
1621FMSG_CHANGELOG_CHANGED_IN_VERSION : Final [str ] = "Changed in *version {}*: {}\n "
1722
18- # marked as deprecated and will be removed in given version
19- FMSG_CHANGELOG_REMOVED_IN_VERSION : Final [str ] = "Removed in *version {}*: {}\n "
20-
21- FMSG_CHANGELOG_DEPRECATED : Final [str ] = (
23+ # marked as deprecated
24+ FMSG_CHANGELOG_DEPRECATED_IN_VERSION : Final [str ] = (
2225 "🚨 **Deprecated**: This endpoint is deprecated and will be removed in a future release.\n "
2326 "Please use `{}` instead.\n \n "
2427)
2528
29+ # marked as deprecated and will be removed in given version
30+ FMSG_CHANGELOG_REMOVED_IN_VERSION : Final [str ] = "Removed in *version {}*: {}\n "
31+
32+
2633DEFAULT_MAX_STRING_LENGTH : Final [int ] = 500
2734
2835
2936def create_route_description (
3037 * ,
3138 base : str = "" ,
32- deprecated : bool = False ,
33- alternative : str | None = None , # alternative route to use
3439 changelog : list [str ] | None = None ,
40+ deprecated_in : str | None = None ,
41+ alternative : str | None = None ,
3542) -> str :
3643 """
3744 Builds a consistent route description with optional deprecation and changelog information.
3845
3946 Args:
4047 base (str): Main route description.
41- deprecated (tuple): (retirement_date, alternative_route) if deprecated.
42- changelog (List[str]): List of formatted changelog strings.
48+ changelog (list[str]): List of formatted changelog strings.
49+ deprecated_in (str, optional): Version when this endpoint was deprecated.
50+ alternative (str, optional): Alternative route to use if deprecated.
4351
4452 Returns:
4553 str: Final description string.
4654 """
4755 parts = []
4856
49- if deprecated :
50- assert alternative , "If deprecated, alternative must be provided" # nosec
51- parts .append (FMSG_CHANGELOG_DEPRECATED .format (alternative ))
57+ if deprecated_in and alternative :
58+ parts .append (FMSG_CHANGELOG_DEPRECATED_IN_VERSION .format (alternative ))
5259
5360 if base :
5461 parts .append (base )
@@ -62,63 +69,63 @@ def create_route_description(
6269def create_route_config (
6370 base_description : str = "" ,
6471 * ,
65- to_be_released_in : str | None = None ,
66- to_be_removed_in : str | None = None ,
67- alternative : str | None = None ,
6872 changelog : list [str ] | None = None ,
6973) -> dict [str , Any ]:
7074 """
71- Creates route configuration options including description.
75+ Creates route configuration options including description based on changelog history.
76+
77+ The function analyzes the changelog to determine if the endpoint:
78+ - Is not yet released (if the earliest entry is in a future version)
79+ - Is deprecated (if there's a removal notice in the changelog)
7280
7381 Args:
7482 base_description: Main route description
75- to_be_released_in: Version where this route will be released (for upcoming features)
76- to_be_removed_in: Version where this route will be removed (for deprecated endpoints)
77- alternative: Alternative route to use (required if to_be_removed_in is provided)
78- changelog: List of formatted changelog strings
83+ changelog: List of formatted changelog strings indicating version history
7984
8085 Returns:
8186 dict: Route configuration options that can be used as kwargs for route decorators
8287 """
8388 route_options : dict [str , Any ] = {}
84-
85- # Build changelog
86- if changelog is None :
87- changelog = []
88-
89- if to_be_released_in :
90- # Add version information to the changelog if not already there
91- version_note = FMSG_CHANGELOG_NEW_IN_VERSION . format ( to_be_released_in )
92- if not any ( version_note in item for item in changelog ) :
93- changelog . append ( version_note )
94- # Hide from schema until released
95- route_options [ "include_in_schema" ] = False
96-
97- if to_be_removed_in :
98- # Require an alternative route if this endpoint will be removed
99- assert ( # nosec
100- alternative
101- ), "If to_be_removed_in is provided, alternative must be provided" # nosec
102-
103- # Add removal notice to the changelog if not already there
104- removal_message = (
105- "This endpoint is deprecated and will be removed in a future version"
106- )
107- removal_note = FMSG_CHANGELOG_REMOVED_IN_VERSION . format (
108- to_be_removed_in , removal_message
109- )
110- if not any ( removal_note in item for item in changelog ):
111- changelog . append ( removal_note )
112-
113- # Mark as deprecated
114- route_options ["deprecated" ] = True
89+ changelog = changelog or []
90+
91+ # Parse changelog to determine endpoint state
92+ is_deprecated = False
93+ alternative = None
94+ is_released = False
95+ current_version = Version ( API_VERSION )
96+
97+ for entry in changelog :
98+ # Check for deprecation/removal entries
99+ if FMSG_CHANGELOG_DEPRECATED_IN_VERSION . split ( "{" )[ 0 ] in entry :
100+ is_deprecated = True
101+ # Extract alternative from deprecation message if possible
102+ with suppress ( IndexError , AttributeError ) :
103+ alternative = entry . split ( "Please use `" )[ 1 ]. split ( "`" )[ 0 ]
104+
105+ # Check for new version entries to determine if this is unreleased
106+ elif FMSG_CHANGELOG_NEW_IN_VERSION . split ( "{" )[ 0 ] in entry :
107+ try :
108+ version_str = entry . split ( "New in *version " )[ 1 ]. split ( "*" )[ 0 ]
109+ entry_version = Version ( version_str )
110+ # If the first/earliest entry version is greater than current API version,
111+ # this endpoint is not yet released
112+ if current_version < entry_version :
113+ is_released = True
114+ except ( IndexError , ValueError , AttributeError ):
115+ pass
116+
117+ # Set route options based on endpoint state
118+ route_options [ "include_in_schema" ] = is_released
119+ route_options ["deprecated" ] = is_deprecated
115120
116121 # Create description
117122 route_options ["description" ] = create_route_description (
118123 base = base_description ,
119- deprecated = bool (to_be_removed_in ),
120- alternative = alternative ,
121124 changelog = changelog ,
125+ deprecated_in = (
126+ "Unknown" if is_deprecated else None
127+ ), # We don't extract exact version
128+ alternative = alternative ,
122129 )
123130
124131 return route_options
0 commit comments