14
14
from flagsmith .analytics import AnalyticsProcessor
15
15
from flagsmith .exceptions import FlagsmithAPIError , FlagsmithClientError
16
16
from flagsmith .models import DefaultFlag , Flags , Segment
17
+ from flagsmith .offline_handlers import BaseOfflineModeHandler
17
18
from flagsmith .polling_manager import EnvironmentDataPollingManager
18
19
from flagsmith .utils .identities import generate_identities_data
19
20
@@ -39,8 +40,8 @@ class Flagsmith:
39
40
40
41
def __init__ (
41
42
self ,
42
- environment_key : str ,
43
- api_url : str = DEFAULT_API_URL ,
43
+ environment_key : str = None ,
44
+ api_url : str = None ,
44
45
custom_headers : typing .Dict [str , typing .Any ] = None ,
45
46
request_timeout_seconds : int = None ,
46
47
enable_local_evaluation : bool = False ,
@@ -49,6 +50,8 @@ def __init__(
49
50
enable_analytics : bool = False ,
50
51
default_flag_handler : typing .Callable [[str ], DefaultFlag ] = None ,
51
52
proxies : typing .Dict [str , str ] = None ,
53
+ offline_mode : bool = True ,
54
+ offline_handler : BaseOfflineModeHandler = None ,
52
55
):
53
56
"""
54
57
:param environment_key: The environment key obtained from Flagsmith interface
@@ -69,37 +72,45 @@ def __init__(
69
72
requested
70
73
:param proxies: as per https://requests.readthedocs.io/en/latest/api/#requests.Session.proxies
71
74
"""
72
- self .session = requests .Session ()
73
- self .session .headers .update (
74
- ** {"X-Environment-Key" : environment_key }, ** (custom_headers or {})
75
- )
76
- self .session .proxies .update (proxies or {})
77
- retries = retries or Retry (total = 3 , backoff_factor = 0.1 )
78
-
79
- self .api_url = api_url if api_url .endswith ("/" ) else f"{ api_url } /"
80
- self .request_timeout_seconds = request_timeout_seconds
81
- self .session .mount (self .api_url , HTTPAdapter (max_retries = retries ))
82
-
83
- self .environment_flags_url = f"{ self .api_url } flags/"
84
- self .identities_url = f"{ self .api_url } identities/"
85
- self .environment_url = f"{ self .api_url } environment-document/"
86
-
87
- self ._environment = None
88
- if enable_local_evaluation :
89
- if not environment_key .startswith ("ser." ):
90
- raise ValueError (
91
- "In order to use local evaluation, please generate a server key "
92
- "in the environment settings page."
93
- )
94
-
95
- self .environment_data_polling_manager_thread = (
96
- EnvironmentDataPollingManager (
97
- main = self ,
98
- refresh_interval_seconds = environment_refresh_interval_seconds ,
99
- daemon = True , # noqa
100
- )
75
+ if offline_mode :
76
+ self .offline_mode = True
77
+ self .offline_handler = offline_handler
78
+ self .update_environment ()
79
+ elif not (environment_key and api_url ):
80
+ raise ValueError ("environment_key and api_url are required." )
81
+ else :
82
+ self .offline_mode = False
83
+ self .session = requests .Session ()
84
+ self .session .headers .update (
85
+ ** {"X-Environment-Key" : environment_key }, ** (custom_headers or {})
101
86
)
102
- self .environment_data_polling_manager_thread .start ()
87
+ self .session .proxies .update (proxies or {})
88
+ retries = retries or Retry (total = 3 , backoff_factor = 0.1 )
89
+
90
+ self .api_url = api_url if api_url .endswith ("/" ) else f"{ api_url } /"
91
+ self .request_timeout_seconds = request_timeout_seconds
92
+ self .session .mount (self .api_url , HTTPAdapter (max_retries = retries ))
93
+
94
+ self .environment_flags_url = f"{ self .api_url } flags/"
95
+ self .identities_url = f"{ self .api_url } identities/"
96
+ self .environment_url = f"{ self .api_url } environment-document/"
97
+
98
+ self ._environment = None
99
+ if enable_local_evaluation :
100
+ if not environment_key .startswith ("ser." ):
101
+ raise ValueError (
102
+ "In order to use local evaluation, please generate a server key "
103
+ "in the environment settings page."
104
+ )
105
+
106
+ self .environment_data_polling_manager_thread = (
107
+ EnvironmentDataPollingManager (
108
+ main = self ,
109
+ refresh_interval_seconds = environment_refresh_interval_seconds ,
110
+ daemon = True , # noqa
111
+ )
112
+ )
113
+ self .environment_data_polling_manager_thread .start ()
103
114
104
115
self ._analytics_processor = (
105
116
AnalyticsProcessor (
@@ -164,7 +175,10 @@ def get_identity_segments(
164
175
return [Segment (id = sm .id , name = sm .name ) for sm in segment_models ]
165
176
166
177
def update_environment (self ):
167
- self ._environment = self ._get_environment_from_api ()
178
+ if self .offline_mode :
179
+ self ._environment = self .offline_handler .get_environment ()
180
+ else :
181
+ self ._environment = self ._get_environment_from_api ()
168
182
169
183
def _get_environment_from_api (self ) -> EnvironmentModel :
170
184
environment_data = self ._get_json_response (self .environment_url , method = "GET" )
0 commit comments