1616This module has required APIs for the clients to use Firebase Remote Config with python.
1717"""
1818
19+ import asyncio
1920import json
2021from typing import Any , Dict , Optional
2122import requests
2526_REMOTE_CONFIG_ATTRIBUTE = '_remoteconfig'
2627
2728class ServerTemplateData :
28- """Represents a Server Template Data class ."""
29+ """Parses, validates and encapsulates template data and metadata ."""
2930 def __init__ (self , etag , template_data ):
3031 """Initializes a new ServerTemplateData instance.
3132
@@ -78,7 +79,7 @@ def conditions(self):
7879
7980
8081class ServerTemplate :
81- """Represents a Server Template with implementations for loading and evaluting the tempalte ."""
82+ """Represents a Server Template with implementations for loading and evaluting the template ."""
8283 def __init__ (self , app : App = None , default_config : Optional [Dict [str , str ]] = None ):
8384 """Initializes a ServerTemplate instance.
8485
@@ -93,14 +94,18 @@ def __init__(self, app: App = None, default_config: Optional[Dict[str, str]] = N
9394 # This gets set when the template is
9495 # fetched from RC servers via the load API, or via the set API.
9596 self ._cache = None
97+ self ._stringified_default_config : Dict [str ,str ] = {}
98+
99+ # RC stores all remote values as string, but it's more intuitive
100+ # to declare default values with specific types, so this converts
101+ # the external declaration to an internal string representation.
96102 if default_config is not None :
97- self ._stringified_default_config = json .dumps (default_config )
98- else :
99- self ._stringified_default_config = None
103+ for key in default_config :
104+ self ._stringified_default_config [key ] = str (default_config [key ])
100105
101106 async def load (self ):
102107 """Fetches the server template and caches the data."""
103- self ._cache = self ._rc_service .get_server_template ()
108+ self ._cache = await self ._rc_service .get_server_template ()
104109
105110 def evaluate (self ):
106111 # Logic to process the cached template into a ServerConfig here.
@@ -157,21 +162,23 @@ def __init__(self, app):
157162 base_url = remote_config_base_url ,
158163 headers = rc_headers , timeout = timeout )
159164
160- def get_server_template (self ):
165+ async def get_server_template (self ):
161166 """Requests for a server template and converts the response to an instance of
162167 ServerTemplateData for storing the template parameters and conditions."""
163- url_prefix = self ._get_url_prefix ()
164168 try :
165- headers , response_json = self ._client .headers_and_body (
166- 'get' , url = url_prefix + '/namespaces/firebase-server/serverRemoteConfig' )
169+ loop = asyncio .get_event_loop ()
170+ headers , template_data = await loop .run_in_executor (None ,
171+ self ._client .headers_and_body ,
172+ 'get' , self ._get_url ())
167173 except requests .exceptions .RequestException as error :
168174 raise self ._handle_remote_config_error (error )
169175 else :
170- return ServerTemplateData (headers .get ('etag' ), response_json )
176+ return ServerTemplateData (headers .get ('etag' ), template_data )
171177
172- def _get_url_prefix (self ):
178+ def _get_url (self ):
173179 """Returns project prefix for url, in the format of /v1/projects/${projectId}"""
174- return "/v1/projects/{0}" .format (self ._project_id )
180+ return "/v1/projects/{0}/namespaces/firebase-server/serverRemoteConfig" .format (
181+ self ._project_id )
175182
176183 @classmethod
177184 def _handle_remote_config_error (cls , error : Any ):
0 commit comments