| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| from typing import Optional | |
| from pypaimon.api.auth.base import AuthProvider | |
| from pypaimon.api.auth.bearer import BearTokenAuthProvider | |
| from pypaimon.api.auth.dlf_provider import DLFAuthProvider | |
| from pypaimon.api.token_loader import DLFToken, DLFTokenLoaderFactory | |
| from pypaimon.common.options import Options | |
| from pypaimon.common.options.config import CatalogOptions | |
| class DLFAuthProviderFactory: | |
| OPENAPI_IDENTIFIER = "openapi" | |
| OPENAPI_V4_IDENTIFIER = "openapi-v4" | |
| DEFAULT_IDENTIFIER = "default" | |
| REGION_PATTERN = r'(?:pre-)?([a-z]+-[a-z]+(?:-\d+)?)' | |
| @staticmethod | |
| def parse_region_from_uri(uri: Optional[str]) -> Optional[str]: | |
| import re | |
| if not uri: | |
| return None | |
| try: | |
| pattern = re.compile(DLFAuthProviderFactory.REGION_PATTERN) | |
| match = pattern.search(uri) | |
| if match: | |
| return match.group(1) | |
| except Exception: | |
| pass | |
| return None | |
| @staticmethod | |
| def parse_signing_algo_from_uri(uri: Optional[str]) -> str: | |
| if not uri: | |
| return DLFAuthProviderFactory.DEFAULT_IDENTIFIER | |
| host = uri.lower() | |
| if host.startswith("http://"): | |
| host = host[7:] | |
| elif host.startswith("https://"): | |
| host = host[8:] | |
| host = host.split('/')[0].split(':')[0] | |
| if "dlfnext" in host: | |
| return DLFAuthProviderFactory.OPENAPI_IDENTIFIER | |
| return DLFAuthProviderFactory.DEFAULT_IDENTIFIER | |
| class AuthProviderFactory: | |
| @staticmethod | |
| def create_auth_provider(options: Options) -> AuthProvider: | |
| provider = options.get(CatalogOptions.TOKEN_PROVIDER) | |
| if provider == 'bear': | |
| token = options.get(CatalogOptions.TOKEN) | |
| return BearTokenAuthProvider(token) | |
| elif provider == 'dlf': | |
| uri = options.get(CatalogOptions.URI) | |
| region = options.get(CatalogOptions.DLF_REGION) | |
| if not region: | |
| region = DLFAuthProviderFactory.parse_region_from_uri(uri) | |
| if not region: | |
| raise ValueError( | |
| "Could not get region from config or URI. " | |
| "Please set 'dlf.region' or use a standard DLF endpoint URI." | |
| ) | |
| # Get signing algorithm from options, or auto-detect from URI | |
| signing_algorithm = options.get(CatalogOptions.DLF_SIGNING_ALGORITHM) | |
| if not signing_algorithm or signing_algorithm == "default": | |
| # Auto-detect based on URI | |
| signing_algorithm = DLFAuthProviderFactory.parse_signing_algo_from_uri(uri) | |
| token_loader = DLFTokenLoaderFactory.create_token_loader(options) | |
| token = ( | |
| DLFToken.from_options(options) | |
| if token_loader is None | |
| else None | |
| ) | |
| return DLFAuthProvider( | |
| uri=uri, | |
| region=region, | |
| signing_algorithm=signing_algorithm, | |
| token=token, | |
| token_loader=token_loader | |
| ) | |
| raise ValueError('Unknown auth provider') |