Skip to content

Commit

Permalink
docs: deprecate google.cloud.firestore_v1.rate_limiter.utcnow (#716)
Browse files Browse the repository at this point in the history
* feat: Replace utcnow and utcfromtimestamp

These will be deprecated starting in Python 3.12.

Replaced:
- `datetime.datetime.utcnow()` with `datetime.datetime.now(tz=datetime.timezone.utc)`

- `datetime.utcfromtimestamp()` with `datetime.fromtimestamp(tz=datetime.timezone.utc)`

* docs: deprecate google.cloud.firestore_v1.rate_limiter.utcnow

* remove usage of  google.cloud.firestore_v1.rate_limiter.utcnow in code

* filter deprecation warning for google.cloud.firestore_v1.rate_limiter.utcnow

---------

Co-authored-by: Anthonios Partheniou <partheniou@google.com>
  • Loading branch information
Mariatta and parthea authored Dec 5, 2023
1 parent 098c8f5 commit 4a74d71
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 202 deletions.
4 changes: 3 additions & 1 deletion google/cloud/firestore_v1/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,9 @@ def build_timestamp(
dt: Optional[Union[DatetimeWithNanoseconds, datetime.datetime]] = None
) -> Timestamp:
"""Returns the supplied datetime (or "now") as a Timestamp"""
return _datetime_to_pb_timestamp(dt or DatetimeWithNanoseconds.utcnow())
return _datetime_to_pb_timestamp(
dt or DatetimeWithNanoseconds.now(tz=datetime.timezone.utc)
)


def compare_timestamps(
Expand Down
8 changes: 6 additions & 2 deletions google/cloud/firestore_v1/bulk_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ def _retry_operation(
elif self._options.retry == BulkRetry.linear:
delay = operation.attempts

run_at = datetime.datetime.utcnow() + datetime.timedelta(seconds=delay)
run_at = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(
seconds=delay
)

# Use of `bisect.insort` maintains the requirement that `self._retries`
# always remain sorted by each object's `run_at` time. Note that it is
Expand Down Expand Up @@ -495,7 +497,9 @@ def _schedule_ready_retries(self):
# ever adding to it via `bisect.insort`), and because `OperationRetry`
# objects are comparable against `datetime` objects, this bisect functionally
# returns the number of retires that are ready for immediate reenlistment.
take_until_index = bisect.bisect(self._retries, datetime.datetime.utcnow())
take_until_index = bisect.bisect(
self._retries, datetime.datetime.now(tz=datetime.timezone.utc)
)

for _ in range(take_until_index):
retry: OperationRetry = self._retries.popleft()
Expand Down
21 changes: 17 additions & 4 deletions google/cloud/firestore_v1/rate_limiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@

import datetime
from typing import NoReturn, Optional
import warnings


def utcnow():
"""
google.cloud.firestore_v1.rate_limiter.utcnow() is deprecated.
Use datetime.datetime.now(datetime.timezone.utc) instead.
"""
warnings.warn(
"google.cloud.firestore_v1.rate_limiter.utcnow() is deprecated. "
"Use datetime.datetime.now(datetime.timezone.utc) instead.",
DeprecationWarning,
)
return datetime.datetime.utcnow()


Expand Down Expand Up @@ -96,8 +106,9 @@ def __init__(
self._phase: int = 0

def _start_clock(self):
self._start = self._start or utcnow()
self._last_refill = self._last_refill or utcnow()
utcnow = datetime.datetime.now(datetime.timezone.utc)
self._start = self._start or utcnow
self._last_refill = self._last_refill or utcnow

def take_tokens(self, num: Optional[int] = 1, allow_less: bool = False) -> int:
"""Returns the number of available tokens, up to the amount requested."""
Expand All @@ -123,7 +134,9 @@ def _check_phase(self):
This is a no-op unless a new [_phase_length] number of seconds since the
start was crossed since it was last called.
"""
age: datetime.timedelta = utcnow() - self._start
age: datetime.timedelta = (
datetime.datetime.now(datetime.timezone.utc) - self._start
)

# Uses integer division to calculate the expected phase. We start in
# Phase 0, so until [_phase_length] seconds have passed, this will
Expand Down Expand Up @@ -152,7 +165,7 @@ def _increase_maximum_tokens(self) -> NoReturn:
def _refill(self) -> NoReturn:
"""Replenishes any tokens that should have regenerated since the last
operation."""
now: datetime.datetime = utcnow()
now: datetime.datetime = datetime.datetime.now(datetime.timezone.utc)
time_since_last_refill: datetime.timedelta = now - self._last_refill

if time_since_last_refill:
Expand Down
1 change: 1 addition & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
UNIT_TEST_EXTERNAL_DEPENDENCIES: List[str] = [
"aiounittest",
"six",
"freezegun",
]
UNIT_TEST_LOCAL_DEPENDENCIES: List[str] = []
UNIT_TEST_DEPENDENCIES: List[str] = []
Expand Down
2 changes: 1 addition & 1 deletion owlbot.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def update_fixup_scripts(library):
templated_files = common.py_library(
samples=False, # set to True only if there are samples
system_test_python_versions=["3.7"],
unit_test_external_dependencies=["aiounittest", "six"],
unit_test_external_dependencies=["aiounittest", "six", "freezegun"],
system_test_external_dependencies=["pytest-asyncio", "six"],
microgenerator=True,
cov_level=100,
Expand Down
9 changes: 4 additions & 5 deletions tests/system/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from google.api_core.exceptions import InvalidArgument
from google.api_core.exceptions import NotFound
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud._helpers import UTC
from google.cloud import firestore_v1 as firestore
from google.cloud.firestore_v1.base_query import FieldFilter, And, Or

Expand Down Expand Up @@ -101,7 +100,7 @@ def test_collections_w_import(database):

@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
def test_create_document(client, cleanup, database):
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
collection_id = "doc-create" + UNIQUE_RESOURCE_ID
document_id = "doc" + UNIQUE_RESOURCE_ID
document = client.document(collection_id, document_id)
Expand Down Expand Up @@ -384,7 +383,7 @@ def check_snapshot(snapshot, document, data, write_result):

@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
def test_document_get(client, cleanup, database):
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
document_id = "for-get" + UNIQUE_RESOURCE_ID
document = client.document("created", document_id)
# Add to clean-up before API request (in case ``create()`` fails).
Expand Down Expand Up @@ -1701,7 +1700,7 @@ def on_snapshot(docs, changes, read_time):
@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
def test_repro_429(client, cleanup, database):
# See: https://github.com/googleapis/python-firestore/issues/429
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
collection = client.collection("repro-429" + UNIQUE_RESOURCE_ID)

for document_id in [f"doc-{doc_id:02d}" for doc_id in range(30)]:
Expand Down Expand Up @@ -1729,7 +1728,7 @@ def test_repro_429(client, cleanup, database):
@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
def test_repro_391(client, cleanup, database):
# See: https://github.com/googleapis/python-firestore/issues/391
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
collection = client.collection("repro-391" + UNIQUE_RESOURCE_ID)

document_ids = [f"doc-{doc_id:02d}" for doc_id in range(30)]
Expand Down
5 changes: 2 additions & 3 deletions tests/system/test_system_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from google.api_core.exceptions import InvalidArgument
from google.api_core.exceptions import NotFound
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud._helpers import UTC
from google.cloud import firestore_v1 as firestore
from google.cloud.firestore_v1.base_query import FieldFilter, And, Or

Expand Down Expand Up @@ -131,7 +130,7 @@ async def test_collections_w_import(database):

@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
async def test_create_document(client, cleanup, database):
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
collection_id = "doc-create" + UNIQUE_RESOURCE_ID
document_id = "doc" + UNIQUE_RESOURCE_ID
document = client.document(collection_id, document_id)
Expand Down Expand Up @@ -416,7 +415,7 @@ def check_snapshot(snapshot, document, data, write_result):

@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
async def test_document_get(client, cleanup, database):
now = datetime.datetime.utcnow().replace(tzinfo=UTC)
now = datetime.datetime.now(tz=datetime.timezone.utc)
document_id = "for-get" + UNIQUE_RESOURCE_ID
document = client.document("created", document_id)
# Add to clean-up before API request (in case ``create()`` fails).
Expand Down
13 changes: 8 additions & 5 deletions tests/unit/v1/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ def test_encode_value_w_datetime_wo_nanos():
dt_nanos = 458816000
# Make sure precision is valid in microseconds too.
assert dt_nanos % 1000 == 0
dt_val = datetime.datetime.utcfromtimestamp(dt_seconds + 1e-9 * dt_nanos)
dt_val = datetime.datetime.fromtimestamp(
dt_seconds + 1e-9 * dt_nanos, tz=datetime.timezone.utc
)

result = encode_value(dt_val)
timestamp_pb = timestamp_pb2.Timestamp(seconds=dt_seconds, nanos=dt_nanos)
Expand Down Expand Up @@ -304,7 +306,9 @@ def test_encode_dict_w_many_types():
dt_nanos = 465964000
# Make sure precision is valid in microseconds too.
assert dt_nanos % 1000 == 0
dt_val = datetime.datetime.utcfromtimestamp(dt_seconds + 1e-9 * dt_nanos)
dt_val = datetime.datetime.fromtimestamp(
dt_seconds + 1e-9 * dt_nanos, tz=datetime.timezone.utc
)

client = _make_client()
document = client.document("most", "adjective", "thing", "here")
Expand Down Expand Up @@ -646,16 +650,15 @@ def test_decode_dict_w_many_types():
from google.protobuf import timestamp_pb2
from google.cloud.firestore_v1.types.document import ArrayValue
from google.cloud.firestore_v1.types.document import MapValue
from google.cloud._helpers import UTC
from google.cloud.firestore_v1.field_path import FieldPath
from google.cloud.firestore_v1._helpers import decode_dict

dt_seconds = 1394037350
dt_nanos = 667285000
# Make sure precision is valid in microseconds too.
assert dt_nanos % 1000 == 0
dt_val = datetime.datetime.utcfromtimestamp(dt_seconds + 1e-9 * dt_nanos).replace(
tzinfo=UTC
dt_val = datetime.datetime.fromtimestamp(
dt_seconds + 1e-9 * dt_nanos, tz=datetime.timezone.utc
)

value_fields = {
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/v1/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ def _doc_get_info(ref_string, values):
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud.firestore_v1 import _helpers

now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
read_time = _datetime_to_pb_timestamp(now)
delta = datetime.timedelta(seconds=100)
update_time = _datetime_to_pb_timestamp(now - delta)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/v1/test_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ def test__parse_batch_get_found():
from google.cloud.firestore_v1.document import DocumentSnapshot
from google.cloud.firestore_v1.base_client import _parse_batch_get

now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
read_time = _datetime_to_pb_timestamp(now)
delta = datetime.timedelta(seconds=100)
update_time = _datetime_to_pb_timestamp(now - delta)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/v1/test_base_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -1994,7 +1994,7 @@ def _make_query_response(**kwargs):
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud.firestore_v1 import _helpers

now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
read_time = _datetime_to_pb_timestamp(now)
kwargs["read_time"] = read_time

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/v1/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def _doc_get_info(ref_string, values):
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud.firestore_v1 import _helpers

now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
read_time = _datetime_to_pb_timestamp(now)
delta = datetime.timedelta(seconds=100)
update_time = _datetime_to_pb_timestamp(now - delta)
Expand Down
Loading

0 comments on commit 4a74d71

Please sign in to comment.