Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ requests, code review feedback, and also pull requests.

## Supported Python Versions

We currently support Python 3.9+. However, Python 3.9 support is deprecated,
and developers are strongly advised to use Python 3.10 or higher. Firebase
Admin Python SDK is also tested on PyPy and
We currently support Python 3.9+. However, Python 3.9 and 3.10 support is
deprecated and will be dropped in an upcoming minor release. Developers are
strongly advised to use Python 3.11 or higher. Firebase Admin Python SDK is
also tested on PyPy and
[Google App Engine](https://cloud.google.com/appengine/) environments.


Expand Down
5 changes: 5 additions & 0 deletions firebase_admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@
from google.auth.credentials import Credentials as GoogleAuthCredentials
from google.auth.exceptions import DefaultCredentialsError
from firebase_admin import credentials
from firebase_admin import _python_version_support
from firebase_admin.__about__ import __version__


# Perform Python version check and emit a support warning if needed.
_python_version_support.check_python_version()


_apps = {}
_apps_lock = threading.RLock()
_clock = datetime.datetime.utcnow
Expand Down
40 changes: 40 additions & 0 deletions firebase_admin/_python_version_support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2026 Google Inc.
#
# Licensed 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.

"""Runtime Python version deprecation check for the Firebase Admin SDK."""

import sys
import warnings

# Minimum Python (major, minor) version that does not emit a deprecation warning.
# Bump this tuple in a minor release to deprecate an older Python version ahead
# of dropping it in a future release.
_MIN_NON_DEPRECATED_VERSION = (3, 11)


def check_python_version() -> None:
"""Emits a FutureWarning if the running Python version is deprecated."""
current = (sys.version_info.major, sys.version_info.minor)
if current < _MIN_NON_DEPRECATED_VERSION:
current_str = f'{current[0]}.{current[1]}'
recommended_str = (
f'{_MIN_NON_DEPRECATED_VERSION[0]}.{_MIN_NON_DEPRECATED_VERSION[1]}'
)
warnings.warn(
f'Support for Python {current_str} in firebase-admin is deprecated '
'and will be dropped in a future minor release. Please upgrade to '
f'Python {recommended_str} or higher to continue receiving updates.',
FutureWarning,
stacklevel=2,
)
56 changes: 56 additions & 0 deletions tests/test_python_version_support.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2026 Google Inc.
#
# Licensed 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.

"""Tests for firebase_admin._python_version_support."""

from collections import namedtuple
from unittest.mock import patch
import warnings

import pytest

from firebase_admin._python_version_support import check_python_version

_VersionInfo = namedtuple('_VersionInfo', ['major', 'minor'])


@pytest.mark.parametrize('version_tuple', [(3, 9), (3, 10)])
def test_deprecated_python_versions_emit_future_warning(version_tuple):
mock_version = _VersionInfo(major=version_tuple[0], minor=version_tuple[1])
version_str = f'{version_tuple[0]}.{version_tuple[1]}'

with patch('firebase_admin._python_version_support.sys.version_info', mock_version):
with pytest.warns(FutureWarning) as record:
check_python_version()

assert len(record) == 1
assert record[0].filename == __file__
expected = (
f'Support for Python {version_str} in firebase-admin is deprecated '
'and will be dropped in a future minor release. Please upgrade to '
'Python 3.11 or higher to continue receiving updates.'
)
assert str(record[0].message) == expected


@pytest.mark.parametrize('version_tuple', [(3, 11), (3, 12), (3, 13), (3, 14), (3, 15)])
def test_supported_python_versions_do_not_warn(version_tuple):
mock_version = _VersionInfo(major=version_tuple[0], minor=version_tuple[1])

with patch('firebase_admin._python_version_support.sys.version_info', mock_version):
with warnings.catch_warnings(record=True) as recorded:
warnings.simplefilter('always')
check_python_version()

assert not recorded
Loading