Skip to content

Commit 449d7cf

Browse files
authored
Deprecate notifications, stabilize GQL statuses in turn (#1209)
1 parent 1316fde commit 449d7cf

28 files changed

+668
-491
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for a full changelog.
167167
- `neo4j.spatial.Point` (and subclasses)
168168
- Separate out log entries that are session-related (including transaction retries)
169169
form sub-logger `neo4j.pool` to a new sub-logger `neo4j.session`.
170+
- Notifications:
171+
- Deprecate notifications and related APIs:
172+
- `ResultSummary.notifications`
173+
- `ResultSummary.summary_notifications`
174+
- `neo4j.SummaryNotification`
175+
- `neo4j.NotificationCategory`
176+
- `neo4j.NotificationDisabledCategory`
177+
- Stabilize GQL status objects (use this instead of notifications):
178+
- `ResultSummary.gql_status_objects`
179+
- `neo4j.GqlStatusObject`
180+
- (`neo4j.exceptions.GqlError`, `neo4j.exceptions.GqlErrorClassification`)
170181

171182

172183
## Version 5.28

docs/source/api.rst

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -687,49 +687,50 @@ See also :attr:`.GqlStatusObject.is_notification`.
687687

688688
``notifications_disabled_categories``
689689
-------------------------------------
690-
Set categories/classifications of notifications the server should not send to the client.
691-
Disabling categories allows the server to skip analysis for those, which can speed up query execution.
690+
Identical to :ref:`driver-notifications-disabled-classifications-ref`.
692691

693-
Notifications are available via :attr:`.ResultSummary.notifications` and :attr:`.ResultSummary.summary_notifications`.
694-
Further, they are surfaced (alongside other status objects) through :attr:`.ResultSummary.gql_status_objects`:
695-
See also :attr:`.GqlStatusObject.is_notification`.
696-
697-
:data:`None` will apply the server's default setting.
698-
699-
If specified together with :ref:`driver-notifications-disabled-classifications-ref`, the settings will be merged.
700-
701-
.. Note::
702-
If configured, the server or all servers of the cluster need to support notifications filtering
703-
(server version 5.7 and newer).
704-
Otherwise, the driver will raise a :exc:`.ConfigurationError` as soon as it encounters a server that does not.
692+
This alias is provided for a consistent naming with :attr:`.SummaryNotification.category`.
705693

706694
:Type: :data:`None`, :term:`iterable` of :class:`.NotificationDisabledCategory` and/or :class:`str`
707695
:Default: :data:`None`
708696

709697
.. versionadded:: 5.7
710698

711-
.. seealso:: :class:`.NotificationDisabledCategory`, session config :ref:`session-notifications-disabled-categories-ref`
699+
.. deprecated:: 6.0
700+
This setting is deprecated in favor of :ref:`driver-notifications-disabled-classifications-ref`.
701+
It will be removed in a future release.
702+
703+
.. seealso:: :class:`.NotificationDisabledCategory`, session config :ref:`session-notifications-disabled-categories-ref`, :attr:`.SummaryNotification.category`
712704

713705

714706
.. _driver-notifications-disabled-classifications-ref:
715707

716708
``notifications_disabled_classifications``
717709
------------------------------------------
718-
Identical to :ref:`driver-notifications-disabled-categories-ref`.
710+
Set classifications/categories of notifications the server should not send to the client.
711+
Disabling classifications allows the server to skip analysis for those, which can speed up query execution.
719712

720-
This alias is provided for a consistent naming with :attr:`.GqlStatusObject.classification`.
713+
Notifications are available via :attr:`.ResultSummary.notifications` and :attr:`.ResultSummary.summary_notifications`.
714+
Further, they are surfaced (alongside other status objects) through :attr:`.ResultSummary.gql_status_objects`:
715+
See also :attr:`.GqlStatusObject.is_notification`.
721716

722-
**This is a preview** (see :ref:`filter-warnings-ref`).
723-
It might be changed without following the deprecation policy.
724-
See also
725-
https://github.com/neo4j/neo4j-python-driver/wiki/preview-features
717+
:data:`None` will apply the server's default setting.
718+
719+
If specified together with :ref:`driver-notifications-disabled-categories-ref`, the settings will be merged.
720+
721+
.. Note::
722+
If configured, the server or all servers of the cluster need to support notifications filtering
723+
(server version 5.7 and newer).
724+
Otherwise, the driver will raise a :exc:`.ConfigurationError` as soon as it encounters a server that does not.
726725

727726
:Type: :data:`None`, :term:`iterable` of :class:`.NotificationDisabledClassification` and/or :class:`str`
728727
:Default: :data:`None`
729728

730729
.. versionadded:: 5.22
731730

732-
.. seealso:: :class:`.NotificationDisabledClassification`, session config :ref:`session-notifications-disabled-classifications-ref`
731+
.. versionchanged:: 6.0 Stabilized from preview.
732+
733+
.. seealso:: :class:`.NotificationDisabledClassification`, session config :ref:`session-notifications-disabled-classifications-ref`, :attr:`.GqlStatusObject.classification`
733734

734735

735736
.. _driver-warn-notification-severity-ref:
@@ -1186,49 +1187,50 @@ See also :attr:`.GqlStatusObject.is_notification`.
11861187

11871188
``notifications_disabled_categories``
11881189
-------------------------------------
1189-
Set categories of notifications the server should not send to the client.
1190-
Disabling categories allows the server to skip analysis for those, which can speed up query execution.
1191-
1192-
Notifications are available via :attr:`.ResultSummary.notifications` and :attr:`.ResultSummary.summary_notifications`.
1193-
Further, they are surfaced (alongside other status objects) through :attr:`.ResultSummary.gql_status_objects`:
1194-
See also :attr:`.GqlStatusObject.is_notification`.
1195-
1196-
:data:`None` will apply the driver's configuration setting (:ref:`driver-notifications-disabled-categories-ref`).
1190+
Identical to :ref:`session-notifications-disabled-classifications-ref`.
11971191

1198-
If specified together with :ref:`session-notifications-disabled-classifications-ref`, the settings will be merged.
1199-
1200-
.. Note::
1201-
If configured, the server or all servers of the cluster need to support notifications filtering
1202-
(server version 5.7 and newer).
1203-
Otherwise, the driver will raise a :exc:`.ConfigurationError` as soon as it encounters a server that does not.
1192+
This alias is provided for a consistent naming with :attr:`.SummaryNotification.category`.
12041193

12051194
:Type: :data:`None`, :term:`iterable` of :class:`.NotificationDisabledCategory` and/or :class:`str`
12061195
:Default: :data:`None`
12071196

12081197
.. versionadded:: 5.7
12091198

1210-
.. seealso:: :class:`.NotificationDisabledCategory`
1199+
.. deprecated:: 6.0
1200+
This setting is deprecated in favor of :ref:`session-notifications-disabled-classifications-ref`.
1201+
It will be removed in a future release.
1202+
1203+
.. seealso:: :class:`.NotificationDisabledCategory`, :attr:`.SummaryNotification.category`
12111204

12121205

12131206
.. _session-notifications-disabled-classifications-ref:
12141207

12151208
``notifications_disabled_classifications``
12161209
------------------------------------------
1217-
Identical to :ref:`session-notifications-disabled-categories-ref`.
1210+
Set classifications/categories of notifications the server should not send to the client.
1211+
Disabling classifications allows the server to skip analysis for those, which can speed up query execution.
12181212

1219-
This alias is provided for a consistent naming with :attr:`.GqlStatusObject.classification`.
1213+
Notifications are available via :attr:`.ResultSummary.notifications` and :attr:`.ResultSummary.summary_notifications`.
1214+
Further, they are surfaced (alongside other status objects) through :attr:`.ResultSummary.gql_status_objects`:
1215+
See also :attr:`.GqlStatusObject.is_notification`.
12201216

1221-
**This is a preview** (see :ref:`filter-warnings-ref`).
1222-
It might be changed without following the deprecation policy.
1223-
See also
1224-
https://github.com/neo4j/neo4j-python-driver/wiki/preview-features
1217+
:data:`None` will apply the driver's configuration setting (:ref:`driver-notifications-disabled-classifications-ref`).
1218+
1219+
If specified together with :ref:`session-notifications-disabled-categories-ref`, the settings will be merged.
1220+
1221+
.. Note::
1222+
If configured, the server or all servers of the cluster need to support notifications filtering
1223+
(server version 5.7 and newer).
1224+
Otherwise, the driver will raise a :exc:`.ConfigurationError` as soon as it encounters a server that does not.
12251225

12261226
:Type: :data:`None`, :term:`iterable` of :class:`.NotificationDisabledClassification` and/or :class:`str`
12271227
:Default: :data:`None`
12281228

12291229
.. versionadded:: 5.22
12301230

1231-
.. seealso:: :class:`.NotificationDisabledClassification`
1231+
.. versionchanged:: 6.0 Stabilized from preview.
1232+
1233+
.. seealso:: :class:`.NotificationDisabledClassification`, :attr:`.GqlStatusObject.classification`
12321234

12331235

12341236

src/neo4j/__init__.py

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515

1616

1717
from . import _typing as _t
18-
from ._api import ( # noqa: F401 dynamic attributes
19-
NotificationCategory,
20-
NotificationDisabledCategory,
21-
NotificationDisabledClassification as _NotificationDisabledClassification,
18+
from ._api import (
19+
NotificationCategory as _NotificationCategory,
20+
NotificationDisabledCategory as _NotificationDisabledCategory,
21+
NotificationDisabledClassification,
2222
NotificationMinimumSeverity,
2323
NotificationSeverity,
2424
RoutingControl,
@@ -59,27 +59,28 @@
5959
)
6060
from ._warnings import (
6161
deprecation_warn as _deprecation_warn,
62-
preview_warn as _preview_warn,
6362
PreviewWarning as _PreviewWarning,
6463
)
65-
from ._work import ( # noqa: F401 dynamic attribute
64+
from ._work import (
6665
EagerResult,
67-
GqlStatusObject as _GqlStatusObject,
68-
NotificationClassification as _NotificationClassification,
66+
GqlStatusObject,
67+
NotificationClassification,
6968
Query,
7069
ResultSummary,
7170
SummaryCounters,
7271
SummaryInputPosition,
73-
SummaryNotification,
72+
SummaryNotification as _SummaryNotification,
7473
unit_of_work,
7574
)
7675

7776

7877
if _t.TYPE_CHECKING:
79-
from ._api import NotificationDisabledClassification
78+
from ._api import (
79+
NotificationCategory,
80+
NotificationDisabledCategory,
81+
)
8082
from ._work import (
81-
GqlStatusObject,
82-
NotificationClassification,
83+
SummaryNotification,
8384
)
8485
from ._warnings import PreviewWarning
8586

@@ -164,18 +165,28 @@
164165

165166

166167
def __getattr__(name) -> _t.Any:
167-
# TODO: 6.0 - remove this
168-
if name in {
169-
"NotificationClassification",
170-
"GqlStatusObject",
171-
"NotificationDisabledClassification",
172-
}:
173-
_preview_warn(
174-
f"{name} is part of GQLSTATUS support, "
175-
"which is a preview feature.",
168+
# TODO: 7.0 - consider removing this
169+
if name == "SummaryNotification":
170+
_deprecation_warn(
171+
"SummaryNotification and related APIs are deprecated. "
172+
"Use GqlStatusObjects and related APIs instead.",
173+
stack_level=2,
174+
)
175+
return _SummaryNotification
176+
if name == "NotificationCategory":
177+
_deprecation_warn(
178+
"NotificationCategory is deprecated. "
179+
"Use NotificationClassification instead.",
180+
stack_level=2,
181+
)
182+
return _NotificationCategory
183+
if name == "NotificationDisabledCategory":
184+
_deprecation_warn(
185+
"NotificationDisabledCategory is deprecated. "
186+
"Use NotificationDisabledClassification instead.",
176187
stack_level=2,
177188
)
178-
return globals()[f"_{name}"]
189+
return _NotificationDisabledCategory
179190
# TODO: 7.0 - remove this
180191
if name == "PreviewWarning":
181192
_deprecation_warn(

src/neo4j/_async/driver.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,10 @@ def driver(
245245
config["encrypted"] = True
246246
config["trusted_certificates"] = TrustAll()
247247

248-
if "notifications_disabled_classifications" in config:
249-
preview_warn(
250-
"notifications_disabled_classifications "
251-
"is a preview feature.",
248+
if "notifications_disabled_categories" in config:
249+
deprecation_warn(
250+
"notifications_disabled_categories is deprecated, "
251+
"use notifications_disabled_classifications instead.",
252252
stack_level=2,
253253
)
254254
_normalize_notifications_config(config, driver_level=True)
@@ -578,10 +578,10 @@ def session(self, **config) -> AsyncSession:
578578
config.pop("warn_notification_severity", None)
579579

580580
self._check_state()
581-
if "notifications_disabled_classifications" in config:
582-
preview_warn(
583-
"notifications_disabled_classifications "
584-
"is a preview feature.",
581+
if "notifications_disabled_categories" in config:
582+
deprecation_warn(
583+
"notifications_disabled_categories is deprecated, "
584+
"use notifications_disabled_classifications instead.",
585585
stack_level=2,
586586
)
587587
session_config = self._read_session_config(config)

src/neo4j/_async/work/result.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
from ... import _typing as t
2929
from ..._api import (
30-
NotificationCategory,
30+
NotificationClassification,
3131
NotificationMinimumSeverity,
3232
NotificationSeverity,
3333
)
@@ -325,21 +325,28 @@ def _handle_warnings(self) -> None:
325325

326326
summary = self._obtain_summary()
327327
query = self._metadata.get("query")
328-
for notification in summary.summary_notifications:
328+
for notification in (
329+
gql_status_object
330+
for gql_status_object in summary.gql_status_objects
331+
if gql_status_object.is_notification
332+
):
329333
log_call = notification_log.debug
330-
if notification.severity_level == NotificationSeverity.INFORMATION:
334+
if notification.severity == NotificationSeverity.INFORMATION:
331335
log_call = notification_log.info
332-
elif notification.severity_level == NotificationSeverity.WARNING:
336+
elif notification.severity == NotificationSeverity.WARNING:
333337
log_call = notification_log.warning
334338
log_call(
335339
"Received notification from DBMS server: %s",
336340
NotificationPrinter(notification, query, one_line=True),
337341
)
338342

339-
if notification.severity_level not in sev_filter:
343+
if notification.severity not in sev_filter:
340344
continue
341345
warning_cls: type[Warning] = Neo4jWarning
342-
if notification.category == NotificationCategory.DEPRECATION:
346+
if (
347+
notification.classification
348+
== NotificationClassification.DEPRECATION
349+
):
343350
warning_cls = Neo4jDeprecationWarning
344351
creation_frame = self._creation_frame
345352
if creation_frame is False:

src/neo4j/_debug/_notification_printer.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@
2020

2121

2222
if t.TYPE_CHECKING:
23-
from .._work import SummaryNotification
23+
from .._work import GqlStatusObject
2424

2525

2626
class NotificationPrinter:
27-
notification: SummaryNotification
27+
notification: GqlStatusObject
2828
query: str | None
2929

3030
def __init__(
3131
self,
32-
notification: SummaryNotification,
32+
notification: GqlStatusObject,
3333
query: str | None = None,
3434
one_line: bool = False,
3535
) -> None:
@@ -39,13 +39,13 @@ def __init__(
3939

4040
def __str__(self):
4141
if self.query is None:
42-
return str(self.notification)
42+
return repr(self.notification)
4343
if self._one_line:
44-
return f"{self.notification} for query: {self.query!r}"
44+
return f"{self.notification!r} for query: {self.query!r}"
4545
pos = self.notification.position
4646
if pos is None:
47-
return f"{self.notification} for query:\n{self.query}"
48-
s = f"{self.notification} for query:\n"
47+
return f"{self.notification!r} for query:\n{self.query}"
48+
s = f"{self.notification!r} for query:\n"
4949
query_lines = self.query.splitlines()
5050
if pos.line <= 0 or pos.line > len(query_lines) or pos.column <= 0:
5151
return s + self.query

src/neo4j/_sync/driver.py

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)