This is an automated email from the ASF dual-hosted git repository.

fokko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git


The following commit(s) were added to refs/heads/main by this push:
     new 50077af9 Deprecate `rest.authorization-url` in favor of 
`oauth2-server-uri` (#962)
50077af9 is described below

commit 50077af9cf951dffc8daa60d29b5443e8dea3093
Author: Andre Luis Anastacio <[email protected]>
AuthorDate: Thu Aug 8 05:49:04 2024 -0300

    Deprecate `rest.authorization-url` in favor of `oauth2-server-uri` (#962)
    
    * Deprecate rest.authorization-url in favor of oauth2-server-uri
    
    * Use deprecation_message instead of deprecated for property deprecation
---
 mkdocs/docs/configuration.md   | 26 +++++++++++++-------------
 mkdocs/docs/contributing.md    | 18 ++++++++++++++++++
 mkdocs/docs/how-to-release.md  | 10 ++++++++++
 pyiceberg/catalog/__init__.py  |  6 +++---
 pyiceberg/catalog/rest.py      | 33 +++++++++++++++++++++++++++++++--
 pyiceberg/utils/deprecated.py  | 33 +++++++++++++++++++++++++--------
 tests/catalog/test_rest.py     |  4 ++--
 tests/utils/test_deprecated.py | 14 ++++++++++++++
 8 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/mkdocs/docs/configuration.md b/mkdocs/docs/configuration.md
index 6bfc5671..3445b5a7 100644
--- a/mkdocs/docs/configuration.md
+++ b/mkdocs/docs/configuration.md
@@ -197,19 +197,19 @@ catalog:
 
 <!-- markdown-link-check-disable -->
 
-| Key                    | Example                          | Description      
                                                                                
  |
-| ---------------------- | -------------------------------- | 
--------------------------------------------------------------------------------------------------
 |
-| uri                    | https://rest-catalog/ws          | URI identifying 
the REST Server                                                                 
   |
-| ugi                    | t-1234:secret                    | Hadoop UGI for 
Hive client.                                                                    
    |
-| credential             | t-1234:secret                    | Credential to 
use for OAuth2 credential flow when initializing the catalog                    
     |
-| token                  | FEW23.DFSDF.FSDF                 | Bearer token 
value to use for `Authorization` header                                         
      |
-| scope                  | openid offline corpds:ds:profile | Desired scope of 
the requested security token (default : catalog)                                
  |
-| resource               | rest_catalog.iceberg.com         | URI for the 
target resource or service                                                      
       |
-| audience               | rest_catalog                     | Logical name of 
target resource or service                                                      
   |
-| rest.sigv4-enabled     | true                             | Sign requests to 
the REST Server using AWS SigV4 protocol                                        
  |
-| rest.signing-region    | us-east-1                        | The region to 
use when SigV4 signing a request                                                
     |
-| rest.signing-name      | execute-api                      | The service 
signing name to use when SigV4 signing a request                                
       |
-| rest.authorization-url | https://auth-service/cc          | Authentication 
URL to use for client credentials authentication (default: uri + 
'v1/oauth/tokens') |
+| Key                 | Example                          | Description         
                                                                               |
+| ------------------- | -------------------------------- | 
--------------------------------------------------------------------------------------------------
 |
+| uri                 | https://rest-catalog/ws          | URI identifying the 
REST Server                                                                    |
+| ugi                 | t-1234:secret                    | Hadoop UGI for Hive 
client.                                                                        |
+| credential          | t-1234:secret                    | Credential to use 
for OAuth2 credential flow when initializing the catalog                        
 |
+| token               | FEW23.DFSDF.FSDF                 | Bearer token value 
to use for `Authorization` header                                               
|
+| scope               | openid offline corpds:ds:profile | Desired scope of 
the requested security token (default : catalog)                                
  |
+| resource            | rest_catalog.iceberg.com         | URI for the target 
resource or service                                                             
|
+| audience            | rest_catalog                     | Logical name of 
target resource or service                                                      
   |
+| rest.sigv4-enabled  | true                             | Sign requests to 
the REST Server using AWS SigV4 protocol                                        
  |
+| rest.signing-region | us-east-1                        | The region to use 
when SigV4 signing a request                                                    
 |
+| rest.signing-name   | execute-api                      | The service signing 
name to use when SigV4 signing a request                                       |
+| oauth2-server-uri   | https://auth-service/cc          | Authentication URL 
to use for client credentials authentication (default: uri + 'v1/oauth/tokens') 
|
 
 <!-- markdown-link-check-enable-->
 
diff --git a/mkdocs/docs/contributing.md b/mkdocs/docs/contributing.md
index beacf0f3..a716f134 100644
--- a/mkdocs/docs/contributing.md
+++ b/mkdocs/docs/contributing.md
@@ -180,6 +180,24 @@ Which will warn:
 Call to load_something, deprecated in 0.1.0, will be removed in 0.2.0. Please 
use load_something_else() instead.
 ```
 
+If you want to remove a property or notify about a behavior change, please add 
a deprecation notice by calling the deprecation_message function:
+
+```python
+from pyiceberg.utils.deprecated import deprecation_message
+
+deprecation_message(
+    deprecated_in="0.1.0",
+    removed_in="0.2.0",
+    help_message="The old_property is deprecated. Please use the 
something_else property instead.",
+)
+```
+
+Which will warn:
+
+```
+Deprecated in 0.1.0, will be removed in 0.2.0. The old_property is deprecated. 
Please use the something_else property instead.
+```
+
 ## Type annotations
 
 For the type annotation the types from the `Typing` package are used.
diff --git a/mkdocs/docs/how-to-release.md b/mkdocs/docs/how-to-release.md
index ce38cbfc..59ad6977 100644
--- a/mkdocs/docs/how-to-release.md
+++ b/mkdocs/docs/how-to-release.md
@@ -38,6 +38,16 @@ For example, the API with the following deprecation tag 
should be removed when p
 )
 ```
 
+We also have the `deprecation_message` function. We need to change the 
behavior according to what is noted in the message of that deprecation.
+
+```python
+deprecation_message(
+    deprecated_in="0.1.0",
+    removed_in="0.2.0",
+    help_message="The old_property is deprecated. Please use the 
something_else property instead.",
+)
+```
+
 ## Running a release candidate
 
 Make sure that the version is correct in `pyproject.toml` and 
`pyiceberg/__init__.py`. Correct means that it reflects the version that you 
want to release.
diff --git a/pyiceberg/catalog/__init__.py b/pyiceberg/catalog/__init__.py
index 02b9f9dd..6469c0d6 100644
--- a/pyiceberg/catalog/__init__.py
+++ b/pyiceberg/catalog/__init__.py
@@ -67,7 +67,7 @@ from pyiceberg.typedef import (
     RecursiveDict,
 )
 from pyiceberg.utils.config import Config, merge_config
-from pyiceberg.utils.deprecated import deprecated
+from pyiceberg.utils.deprecated import deprecation_message
 
 if TYPE_CHECKING:
     import pyarrow as pa
@@ -742,11 +742,11 @@ class MetastoreCatalog(Catalog, ABC):
 
         for property_name in DEPRECATED_PROPERTY_NAMES:
             if self.properties.get(property_name):
-                deprecated(
+                deprecation_message(
                     deprecated_in="0.7.0",
                     removed_in="0.8.0",
                     help_message=f"The property {property_name} is deprecated. 
Please use properties that start with client., glue., and dynamo. instead",
-                )(lambda: None)()
+                )
 
     def create_table_transaction(
         self,
diff --git a/pyiceberg/catalog/rest.py b/pyiceberg/catalog/rest.py
index 813398fa..639d732b 100644
--- a/pyiceberg/catalog/rest.py
+++ b/pyiceberg/catalog/rest.py
@@ -71,7 +71,8 @@ from pyiceberg.table.metadata import TableMetadata
 from pyiceberg.table.sorting import UNSORTED_SORT_ORDER, SortOrder, 
assign_fresh_sort_order_ids
 from pyiceberg.typedef import EMPTY_DICT, UTF8, IcebergBaseModel, Identifier, 
Properties
 from pyiceberg.types import transform_dict_value_to_str
-from pyiceberg.utils.properties import property_as_bool
+from pyiceberg.utils.deprecated import deprecation_message
+from pyiceberg.utils.properties import get_first_property_value, 
property_as_bool
 
 if TYPE_CHECKING:
     import pyarrow as pa
@@ -120,6 +121,7 @@ SIGV4 = "rest.sigv4-enabled"
 SIGV4_REGION = "rest.signing-region"
 SIGV4_SERVICE = "rest.signing-name"
 AUTH_URL = "rest.authorization-url"
+OAUTH2_SERVER_URI = "oauth2-server-uri"
 HEADER_PREFIX = "header."
 
 NAMESPACE_SEPARATOR = b"\x1f".decode(UTF8)
@@ -291,11 +293,38 @@ class RestCatalog(Catalog):
 
     @property
     def auth_url(self) -> str:
-        if url := self.properties.get(AUTH_URL):
+        if self.properties.get(AUTH_URL):
+            deprecation_message(
+                deprecated_in="0.8.0",
+                removed_in="0.9.0",
+                help_message=f"The property {AUTH_URL} is deprecated. Please 
use {OAUTH2_SERVER_URI} instead",
+            )
+
+        self._warn_oauth_tokens_deprecation()
+
+        if url := get_first_property_value(self.properties, AUTH_URL, 
OAUTH2_SERVER_URI):
             return url
         else:
             return self.url(Endpoints.get_token, prefixed=False)
 
+    def _warn_oauth_tokens_deprecation(self) -> None:
+        has_oauth_server_uri = OAUTH2_SERVER_URI in self.properties
+        has_credential = CREDENTIAL in self.properties
+        has_init_token = TOKEN in self.properties
+        has_sigv4_enabled = property_as_bool(self.properties, SIGV4, False)
+
+        if not has_oauth_server_uri and (has_init_token or has_credential) and 
not has_sigv4_enabled:
+            deprecation_message(
+                deprecated_in="0.8.0",
+                removed_in="1.0.0",
+                help_message="Iceberg REST client is missing the OAuth2 server 
URI "
+                f"configuration and defaults to 
{self.uri}{Endpoints.get_token}. "
+                "This automatic fallback will be removed in a future Iceberg 
release."
+                f"It is recommended to configure the OAuth2 endpoint using the 
'{OAUTH2_SERVER_URI}'"
+                "property to be prepared. This warning will disappear if the 
OAuth2"
+                "endpoint is explicitly configured. See 
https://github.com/apache/iceberg/issues/10537";,
+            )
+
     def _extract_optional_oauth_params(self) -> Dict[str, str]:
         optional_oauth_param = {SCOPE: self.properties.get(SCOPE) or 
CATALOG_SCOPE}
         set_of_optional_params = {AUDIENCE, RESOURCE}
diff --git a/pyiceberg/utils/deprecated.py b/pyiceberg/utils/deprecated.py
index 0de8cbfa..92051b4f 100644
--- a/pyiceberg/utils/deprecated.py
+++ b/pyiceberg/utils/deprecated.py
@@ -30,16 +30,33 @@ def deprecated(deprecated_in: str, removed_in: str, 
help_message: Optional[str]
     def decorator(func: Callable):  # type: ignore
         @functools.wraps(func)
         def new_func(*args: Any, **kwargs: Any) -> Any:
-            warnings.simplefilter("always", DeprecationWarning)  # turn off 
filter
-
-            warnings.warn(
-                f"Call to {func.__name__}, deprecated in {deprecated_in}, will 
be removed in {removed_in}.{help_message}",
-                category=DeprecationWarning,
-                stacklevel=2,
-            )
-            warnings.simplefilter("default", DeprecationWarning)  # reset 
filter
+            message = f"Call to {func.__name__}, deprecated in 
{deprecated_in}, will be removed in {removed_in}.{help_message}"
+
+            _deprecation_warning(message)
+
             return func(*args, **kwargs)
 
         return new_func
 
     return decorator
+
+
+def deprecation_message(deprecated_in: str, removed_in: str, help_message: 
Optional[str]) -> None:
+    """Mark properties or behaviors as deprecated.
+
+    Adding this will result in a warning being emitted.
+    """
+    message = f"Deprecated in {deprecated_in}, will be removed in 
{removed_in}. {help_message}"
+
+    _deprecation_warning(message)
+
+
+def _deprecation_warning(message: str) -> None:
+    warnings.simplefilter("always", DeprecationWarning)  # turn off filter
+
+    warnings.warn(
+        message,
+        category=DeprecationWarning,
+        stacklevel=2,
+    )
+    warnings.simplefilter("default", DeprecationWarning)  # reset filter
diff --git a/tests/catalog/test_rest.py b/tests/catalog/test_rest.py
index fe9a32fe..174fff5d 100644
--- a/tests/catalog/test_rest.py
+++ b/tests/catalog/test_rest.py
@@ -24,7 +24,7 @@ from requests_mock import Mocker
 
 import pyiceberg
 from pyiceberg.catalog import PropertiesUpdateSummary, load_catalog
-from pyiceberg.catalog.rest import AUTH_URL, RestCatalog
+from pyiceberg.catalog.rest import OAUTH2_SERVER_URI, RestCatalog
 from pyiceberg.exceptions import (
     AuthorizationExpiredError,
     NamespaceAlreadyExistsError,
@@ -235,7 +235,7 @@ def test_token_200_w_auth_url(rest_mock: Mocker) -> None:
     )
     # pylint: disable=W0212
     assert (
-        RestCatalog("rest", uri=TEST_URI, credential=TEST_CREDENTIALS, 
**{AUTH_URL: TEST_AUTH_URL})._session.headers[
+        RestCatalog("rest", uri=TEST_URI, credential=TEST_CREDENTIALS, 
**{OAUTH2_SERVER_URI: TEST_AUTH_URL})._session.headers[
             "Authorization"
         ]
         == f"Bearer {TEST_TOKEN}"
diff --git a/tests/utils/test_deprecated.py b/tests/utils/test_deprecated.py
index 7c44c458..a77ed665 100644
--- a/tests/utils/test_deprecated.py
+++ b/tests/utils/test_deprecated.py
@@ -35,3 +35,17 @@ def test_deprecated(warn: Mock) -> None:
     assert warn.call_args[0] == (
         "Call to deprecated_method, deprecated in 0.1.0, will be removed in 
0.2.0. Please use load_something_else() instead.",
     )
+
+
+@patch("warnings.warn")
+def test_deprecation_message(warn: Mock) -> None:
+    from pyiceberg.utils.deprecated import deprecation_message
+
+    deprecation_message(
+        deprecated_in="0.1.0",
+        removed_in="0.2.0",
+        help_message="Please use something_else instead",
+    )
+
+    assert warn.called
+    assert warn.call_args[0] == ("Deprecated in 0.1.0, will be removed in 
0.2.0. Please use something_else instead",)

Reply via email to