51 lines
2.4 KiB
Python
51 lines
2.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
import logging
|
||
import re
|
||
from typing import Dict, Any
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
def format_url_with_path_params(path_template: str, path_params: Dict[str, Any]) -> str:
|
||
"""
|
||
使用提供的路径参数格式化URL路径模板。
|
||
例如, path_template='/users/{userId}/items/{itemId}'
|
||
path_params={'userId': 123, 'itemId': 'abc'}
|
||
-> '/users/123/items/abc'
|
||
|
||
Args:
|
||
path_template: 包含占位符的URL路径,例如 /resource/{id}。
|
||
path_params: 包含占位符名称及其值的字典。
|
||
|
||
Returns:
|
||
格式化后的URL路径。
|
||
"""
|
||
url = path_template
|
||
try:
|
||
# 优先使用 .format(**path_params) 如果所有占位符都能匹配
|
||
# 这要求 path_params 中的键与模板中的占位符完全对应
|
||
# url = path_template.format(**path_params) # 更简洁,但如果参数不完全匹配会报错
|
||
|
||
# 使用正则表达式逐个替换更安全,可以处理部分参数或额外参数的情况
|
||
for param_name, param_value in path_params.items():
|
||
placeholder = f"{{{param_name}}}"
|
||
if placeholder in url:
|
||
url = url.replace(placeholder, str(param_value))
|
||
else:
|
||
# Log if a path param was provided but not found in template. Could be optional.
|
||
logger.debug(f"Path parameter '{param_name}' provided but placeholder '{placeholder}' not found in template '{path_template}'.")
|
||
|
||
# 检查是否还有未替换的占位符 (可选,但推荐)
|
||
remaining_placeholders = re.findall(r"({[^{}]+?})", url)
|
||
if remaining_placeholders:
|
||
logger.warning(f"URL '{url}' 中仍有未替换的路径参数占位符: {remaining_placeholders}。原始模板: '{path_template}', 提供参数: {path_params}")
|
||
|
||
except KeyError as e:
|
||
logger.error(f"格式化URL路径 '{path_template}' 失败:路径参数 '{e}' 未在提供的 path_params 中找到。可用参数: {list(path_params.keys())}")
|
||
# 根据需要,这里可以选择是返回原始模板还是抛出异常
|
||
# return path_template
|
||
raise ValueError(f"Missing path parameter {e} for URL template {path_template}") from e
|
||
except Exception as e:
|
||
logger.error(f"格式化URL路径 '{path_template}' 时发生未知错误: {e}")
|
||
raise # 或者返回原始模板
|
||
|
||
return url |