8000 Simplify parsing logic again! · ClarkDing/firebase-admin-python@d26eb29 · GitHub
[go: up one dir, main page]

Skip to content

Commit d26eb29

Browse files
committed
Simplify parsing logic again!
1 parent 3ca46f6 commit d26eb29

File tree

3 files changed

+53
-60
lines changed

3 files changed

+53
-60
lines changed

firebase_admin/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,8 @@ def _lookup_project_id(self):
264264
if not project_id:
265265
project_id = os.environ.get('GOOGLE_CLOUD_PROJECT',
266266
os.environ.get('GCLOUD_PROJECT'))
267-
if project_id:
268-
return project_id
269-
else:
270-
return None
267+
App._validate_project_id(self._options.get('projectId'))
268+
return project_id
271269

272270
def _get_service(self, name, initializer):
273271
"""Returns the service instance identified by the given name.

firebase_admin/db.py

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -800,81 +800,81 @@ def get_client(self, db_url=None):
800800
"""Creates a client based on the db_url. Clients may be cached."""
801801
if db_url is None:
802802
db_url = self._db_url
803-
base_url, params, use_fake_creds = \
804-
_DatabaseService._parse_db_url(db_url, self._emulator_host)
803+
804+
base_url, namespace = _DatabaseService._parse_db_url(db_url, self._emulator_host)
805+
if base_url == 'https://{0}.firebaseio.com'.format(namespace):
806+
# Production base_url. No need to specify namespace in query params.
807+
params = {}
808+
credential = self._credential.get_credential()
809+
else:
810+
# Emulator base_url. Use fake credentials and specify ?ns=foo in query params.
811+
credential = _EmulatorAdminCredentials()
812+
params = {'ns': namespace}
805813
if self._auth_override:
806814
params['auth_variable_override'] = self._auth_override
807815

808816
client_cache_key = (base_url, json.dumps(params, sort_keys=True))
809817
if client_cache_key not in self._clients:
810-
if use_fake_creds:
811-
credential = _EmulatorAdminCredentials()
812-
else:
813-
credential = self._credential.get_creden 10000 tial()
814818
client = _Client(credential, base_url, self._timeout, params)
815819
self._clients[client_cache_key] = client
816820
return self._clients[client_cache_key]
817821

818822
@classmethod
819823
def _parse_db_url(cls, url, emulator_host=None):
820-
"""Parses a database URL into (base_url, query_params, use_fake_creds).
824+
"""Parses (base_url, namespace) from a database URL.
821825
822826
The input can be either a production URL (https://foo-bar.firebaseio.com/)
823-
or an Emulator URL (http://localhost:8080/?ns=foo-bar). The resulting
824-
base_url never includes query params. Any required query parameters will
825-
be returned separately as a map (e.g. `{"ns": "foo-bar"}`).
827+
or an Emulator URL (http://localhost:8080/?ns=foo-bar). In case of Emulator
828+
URL, the namespace is extracted from the query param ns. The resulting
829+
base_url never includes query params.
826830
827831
If url is a production URL and emulator_host is specified, the result
828-
base URL will use emulator_host, with a ns query parameter indicating
829-
the namespace, parsed from the production URL. emulator_host is ignored
830-
if url is already an emulator URL. In either case, use_fake_creds will
831-
be set to True.
832+
base URL will use emulator_host instead. emulator_host is ignored
833+
if url is already an emulator URL.
832834
"""
833835
if not url or not isinstance(url, six.string_types):
834836
raise ValueError(
835837
'Invalid database URL: "{0}". Database URL must be a non-empty '
836838
'URL string.'.format(url))
837839
parsed_url = urllib.parse.urlparse(url)
838-
use_fake_creds = False
839840
if parsed_url.netloc.endswith('.firebaseio.com'):
840-
if parsed_url.scheme != 'https':
841-
raise ValueError(
842-
'Invalid database URL: "{0}". Database URL must be an HTTPS URL.'.format(url))
843-
# pylint: disable=invalid-name
844-
base_url, namespace = cls._parse_production_url(parsed_url)
845-
if emulator_host:
846-
base_url = 'http://{0}'.format(emulator_host)
847-
use_fake_creds = True
841+
base_url, namespace = cls._parse_production_url(parsed_url, emulator_host)
848842
else:
849-
use_fake_creds = True
850843
base_url, namespace = cls._parse_emulator_url(parsed_url)
851844

852-
if not base_url or not namespace:
845+
return base_url, namespace
846+
847+
@classmethod
848+
def _parse_production_url(cls, parsed_url, emulator_host):
849+
# Handle production URL like https://foo-bar.firebaseio.com/
850+
if parsed_url.scheme != 'https':
851+
raise ValueError(
852+
'Invalid database URL scheme: "{0}". Database URL must be an HTTPS URL.'.format(
853+
parsed_url.scheme))
854+
namespace = parsed_url.netloc.split('.')[0]
855+
if not namespace:
853856
raise ValueError(
854857
'Invalid database URL: "{0}". Database URL must be a valid URL to a '
855-
'Firebase Realtime Database instance.'.format(url))
856-
if base_url == 'https://{0}.firebaseio.com'.format(namespace):
857-
# namespace can be inferred from the base_url. No need for query params.
858-
return base_url, {}, use_fake_creds
859-
else:
860-
# ?ns=foo is needed.
861-
return base_url, {'ns': namespace}, use_fake_creds
858+
'Firebase Realtime Database instance.'.format(parsed_url.geturl()))
862859

863-
@classmethod
864-
def _parse_production_url(cls, parsed_url):
865-
base_url = 'https://{0}'.format(parsed_url.netloc)
866-
return base_url, parsed_url.netloc.split('.')[0]
860+
if emulator_host:
861+
base_url = 'http://{0}'.format(emulator_host)
862+
else:
863+
base_url = 'https://{0}'.format(parsed_url.netloc)
864+
return base_url, namespace
867865

868866
@classmethod
869867
def _parse_emulator_url(cls, parsed_url):
870868
# Handle emulator URL like http://localhost:8080/?ns=foo-bar
871869
query_ns = urllib.parse.parse_qs(parsed_url.query).get('ns')
872-
if parsed_url.scheme == 'http':
873-
if query_ns and len(query_ns) == 1 and query_ns[0]:
874-
base_url = '{0}://{1}'.format(parsed_url.scheme, parsed_url.netloc)
875-
return base_url, query_ns[0]
870+
if parsed_url.scheme != 'http' or (not query_ns or len(query_ns) != 1 or not query_ns[0]):
871+
raise ValueError(
872+
'Invalid database URL: "{0}". Database URL must be a valid URL to a '
873+
'Firebase Realtime Database instance.'.format(parsed_url.geturl()))
876874

877-
return None, None
875+
namespace = query_ns[0]
876+
base_url = '{0}://{1}'.format(parsed_url.scheme, parsed_url.netloc)
877+
return base_url, namespace
878878

879879
@classmethod
880880
def _get_auth_override(cls, app):

tests/test_db.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -624,31 +624,26 @@ def test_no_db_url(self):
624624
db.reference()
625625

626626
@pytest.mark.parametrize(
627-
'url,emulator_host,expected_base_url,expected_params,expected_use_fake_creds',
627+
'url,emulator_host,expected_base_url,expected_namespace',
628628
[
629629
# Production URLs with no override:
630-
('https://test.firebaseio.com', None, 'https://test.firebaseio.com', {}, False),
631-
('https://test.firebaseio.com/', None, 'https://test.firebaseio.com', {}, False),
630+
('https://test.firebaseio.com', None, 'https://test.firebaseio.com', 'test'),
631+
('https://test.firebaseio.com/', None, 'https://test.firebaseio.com', 'test'),
632632
633633
# Production URLs with emulator_host override:
634-
('https://test.firebaseio.com', 'localhost:9000',
635-
'http://localhost:9000', {'ns': 'test'}, True),
636-
('https://test.firebaseio.com/', 'localhost:9000',
637-
'http://localhost:9000', {'ns': 'test'}, True),
634+
('https://test.firebaseio.com', 'localhost:9000', 'http://localhost:9000', 'test'),
635+
('https://test.firebaseio.com/', 'localhost:9000', 'http://localhost:9000', 'test'),
638636
639637
# Emulator URLs with no override.
640-
('http://localhost:8000/?ns=test', None, 'http://localhost:8000', {'ns': 'test'}, True),
638+
('http://localhost:8000/?ns=test', None, 'http://localhost:8000', 'test'),
641639
# emulator_host is ignored when the original URL is already emulator.
642-
('http://localhost:8000/?ns=test', 'localhost:9999',
643-
'http://localhost:8000', {'ns': 'test'}, True),
640+
('http://localhost:8000/?ns=test', 'localhost:9999', 'http://localhost:8000', 'test'),
644641
]
645642
)
646-
def test_parse_db_url(self, url, emulator_host, expected_base_url,
647-
expected_params, expected_use_fake_creds):
648-
base_url, params, use_fake_creds = db._DatabaseService._parse_db_url(url, emulator_host)
643+
def test_parse_db_url(self, url, emulator_host, expected_base_url, expected_namespace):
644+
base_url, namespace = db._DatabaseService._parse_db_url(url, emulator_host)
649645
assert base_url == expected_base_url
650-
assert params == expected_params
651-
assert use_fake_creds == expected_use_fake_creds
646+
assert namespace == expected_namespace
652647

653648
@pytest.mark.parametrize('url,emulator_host', [
654649
('', None),

0 commit comments

Comments
 (0)
0