langfun 0.1.2.dev202510300805__py3-none-any.whl → 0.1.2.dev202511010804__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of langfun might be problematic. Click here for more details.

@@ -0,0 +1,255 @@
1
+ # Copyright 2025 The Langfun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """Environment event handler chain."""
15
+
16
+ from typing import Sequence
17
+ from langfun.env import interface
18
+
19
+
20
+ class EventHandlerChain(interface.EventHandler):
21
+ """Environment event handler chain."""
22
+
23
+ def __init__(self, handlers: Sequence[interface.EventHandler]):
24
+ super().__init__()
25
+ self._handlers = list(handlers)
26
+
27
+ def add(self, handler: interface.EventHandler):
28
+ self._handlers.append(handler)
29
+
30
+ def remove(self, handler: interface.EventHandler):
31
+ self._handlers.remove(handler)
32
+
33
+ def on_environment_starting(
34
+ self,
35
+ environment: interface.Environment,
36
+ ) -> None:
37
+ """Called when the environment is starting."""
38
+ for handler in self._handlers:
39
+ handler.on_environment_starting(environment)
40
+
41
+ def on_environment_shutting_down(
42
+ self,
43
+ environment: interface.Environment,
44
+ offline_duration: float,
45
+ ) -> None:
46
+ """Called when the environment is shutting down."""
47
+ for handler in self._handlers:
48
+ handler.on_environment_shutting_down(environment, offline_duration)
49
+
50
+ def on_environment_start(
51
+ self,
52
+ environment: interface.Environment,
53
+ duration: float,
54
+ error: BaseException | None
55
+ ) -> None:
56
+ """Called when the environment is started."""
57
+ for handler in self._handlers:
58
+ handler.on_environment_start(environment, duration, error)
59
+
60
+ def on_environment_housekeep(
61
+ self,
62
+ environment: interface.Environment,
63
+ counter: int,
64
+ duration: float,
65
+ error: BaseException | None,
66
+ **kwargs
67
+ ) -> None:
68
+ """Called when the environment is housekeeping."""
69
+ for handler in self._handlers:
70
+ handler.on_environment_housekeep(
71
+ environment, counter, duration, error, **kwargs
72
+ )
73
+
74
+ def on_environment_shutdown(
75
+ self,
76
+ environment: interface.Environment,
77
+ duration: float,
78
+ lifetime: float,
79
+ error: BaseException | None
80
+ ) -> None:
81
+ """Called when the environment is shutdown."""
82
+ for handler in self._handlers:
83
+ handler.on_environment_shutdown(environment, duration, lifetime, error)
84
+
85
+ def on_sandbox_start(
86
+ self,
87
+ environment: interface.Environment,
88
+ sandbox: interface.Sandbox,
89
+ duration: float,
90
+ error: BaseException | None
91
+ ) -> None:
92
+ for handler in self._handlers:
93
+ handler.on_sandbox_start(environment, sandbox, duration, error)
94
+
95
+ def on_sandbox_status_change(
96
+ self,
97
+ environment: interface.Environment,
98
+ sandbox: interface.Sandbox,
99
+ old_status: interface.Sandbox.Status,
100
+ new_status: interface.Sandbox.Status,
101
+ span: float
102
+ ) -> None:
103
+ for handler in self._handlers:
104
+ handler.on_sandbox_status_change(
105
+ environment, sandbox, old_status, new_status, span
106
+ )
107
+
108
+ def on_sandbox_shutdown(
109
+ self,
110
+ environment: interface.Environment,
111
+ sandbox: interface.Sandbox,
112
+ duration: float,
113
+ lifetime: float,
114
+ error: BaseException | None
115
+ ) -> None:
116
+ for handler in self._handlers:
117
+ handler.on_sandbox_shutdown(
118
+ environment, sandbox, duration, lifetime, error
119
+ )
120
+
121
+ def on_sandbox_housekeep(
122
+ self,
123
+ environment: interface.Environment,
124
+ sandbox: interface.Sandbox,
125
+ counter: int,
126
+ duration: float,
127
+ error: BaseException | None,
128
+ **kwargs
129
+ ) -> None:
130
+ """Called when a sandbox feature is housekeeping."""
131
+ for handler in self._handlers:
132
+ handler.on_sandbox_housekeep(
133
+ environment, sandbox, counter, duration, error, **kwargs
134
+ )
135
+
136
+ def on_feature_setup(
137
+ self,
138
+ environment: interface.Environment,
139
+ sandbox: interface.Sandbox,
140
+ feature: interface.Feature,
141
+ duration: float,
142
+ error: BaseException | None
143
+ ) -> None:
144
+ """Called when a sandbox feature is setup."""
145
+ for handler in self._handlers:
146
+ handler.on_feature_setup(
147
+ environment, sandbox, feature, duration, error
148
+ )
149
+
150
+ def on_feature_teardown(
151
+ self,
152
+ environment: interface.Environment,
153
+ sandbox: interface.Sandbox,
154
+ feature: interface.Feature,
155
+ duration: float,
156
+ error: BaseException | None
157
+ ) -> None:
158
+ """Called when a sandbox feature is teardown."""
159
+ for handler in self._handlers:
160
+ handler.on_feature_teardown(
161
+ environment, sandbox, feature, duration, error
162
+ )
163
+
164
+ def on_feature_setup_session(
165
+ self,
166
+ environment: interface.Environment,
167
+ sandbox: interface.Sandbox,
168
+ feature: interface.Feature,
169
+ session_id: str | None,
170
+ duration: float,
171
+ error: BaseException | None
172
+ ) -> None:
173
+ """Called when a sandbox feature is setup."""
174
+ for handler in self._handlers:
175
+ handler.on_feature_setup_session(
176
+ environment, sandbox, feature, session_id, duration, error
177
+ )
178
+
179
+ def on_feature_teardown_session(
180
+ self,
181
+ environment: interface.Environment,
182
+ sandbox: interface.Sandbox,
183
+ feature: interface.Feature,
184
+ session_id: str,
185
+ duration: float,
186
+ error: BaseException | None
187
+ ) -> None:
188
+ """Called when a sandbox feature is teardown."""
189
+ for handler in self._handlers:
190
+ handler.on_feature_teardown_session(
191
+ environment, sandbox, feature, session_id, duration, error
192
+ )
193
+
194
+ def on_feature_housekeep(
195
+ self,
196
+ environment: interface.Environment,
197
+ sandbox: interface.Sandbox,
198
+ feature: interface.Feature,
199
+ counter: int,
200
+ duration: float,
201
+ error: BaseException | None,
202
+ **kwargs
203
+ ) -> None:
204
+ """Called when a sandbox feature is housekeeping."""
205
+ for handler in self._handlers:
206
+ handler.on_feature_housekeep(
207
+ environment, sandbox, feature, counter, duration, error, **kwargs
208
+ )
209
+
210
+ def on_session_start(
211
+ self,
212
+ environment: interface.Environment,
213
+ sandbox: interface.Sandbox,
214
+ session_id: str,
215
+ duration: float,
216
+ error: BaseException | None
217
+ ) -> None:
218
+ """Called when a sandbox session starts."""
219
+ for handler in self._handlers:
220
+ handler.on_session_start(
221
+ environment, sandbox, session_id, duration, error
222
+ )
223
+
224
+ def on_session_end(
225
+ self,
226
+ environment: interface.Environment,
227
+ sandbox: interface.Sandbox,
228
+ session_id: str,
229
+ duration: float,
230
+ lifetime: float,
231
+ error: BaseException | None
232
+ ) -> None:
233
+ """Called when a sandbox session ends."""
234
+ for handler in self._handlers:
235
+ handler.on_session_end(
236
+ environment, sandbox, session_id, duration, lifetime, error
237
+ )
238
+
239
+ def on_sandbox_activity(
240
+ self,
241
+ name: str,
242
+ environment: interface.Environment,
243
+ sandbox: interface.Sandbox,
244
+ feature: interface.Feature | None,
245
+ session_id: str | None,
246
+ duration: float,
247
+ error: BaseException | None,
248
+ **kwargs
249
+ ) -> None:
250
+ """Called when a sandbox activity is performed."""
251
+ for handler in self._handlers:
252
+ handler.on_sandbox_activity(
253
+ name, environment, sandbox, feature, session_id, duration, error,
254
+ **kwargs
255
+ )
@@ -0,0 +1,281 @@
1
+ # Copyright 2025 The Langfun Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import unittest
16
+ from langfun.env import interface
17
+ from langfun.env.event_handlers import chain
18
+
19
+
20
+ class MockEventHandler(interface.EventHandler):
21
+
22
+ def __init__(self):
23
+ self.calls = []
24
+
25
+ def _record_call(self, method_name, *args, **kwargs):
26
+ self.calls.append((method_name, args, kwargs))
27
+
28
+ def on_environment_starting(self, environment):
29
+ self._record_call('on_environment_starting', environment)
30
+
31
+ def on_environment_shutting_down(self, environment, offline_duration):
32
+ self._record_call(
33
+ 'on_environment_shutting_down', environment, offline_duration
34
+ )
35
+
36
+ def on_environment_start(self, environment, duration, error):
37
+ self._record_call('on_environment_start', environment, duration, error)
38
+
39
+ def on_environment_housekeep(
40
+ self, environment, counter, duration, error, **kwargs
41
+ ):
42
+ self._record_call(
43
+ 'on_environment_housekeep',
44
+ environment, counter, duration, error, **kwargs
45
+ )
46
+
47
+ def on_environment_shutdown(self, environment, duration, lifetime, error):
48
+ self._record_call(
49
+ 'on_environment_shutdown', environment, duration, lifetime, error
50
+ )
51
+
52
+ def on_sandbox_start(self, environment, sandbox, duration, error):
53
+ self._record_call('on_sandbox_start', environment, sandbox, duration, error)
54
+
55
+ def on_sandbox_status_change(
56
+ self, environment, sandbox, old_status, new_status, span
57
+ ):
58
+ self._record_call(
59
+ 'on_sandbox_status_change',
60
+ environment,
61
+ sandbox,
62
+ old_status,
63
+ new_status,
64
+ span,
65
+ )
66
+
67
+ def on_sandbox_shutdown(
68
+ self, environment, sandbox, duration, lifetime, error
69
+ ):
70
+ self._record_call(
71
+ 'on_sandbox_shutdown', environment, sandbox, duration, lifetime, error
72
+ )
73
+
74
+ def on_sandbox_housekeep(
75
+ self, environment, sandbox, counter, duration, error, **kwargs
76
+ ):
77
+ self._record_call(
78
+ 'on_sandbox_housekeep',
79
+ environment,
80
+ sandbox,
81
+ counter,
82
+ duration,
83
+ error,
84
+ **kwargs,
85
+ )
86
+
87
+ def on_feature_setup(self, environment, sandbox, feature, duration, error):
88
+ self._record_call(
89
+ 'on_feature_setup', environment, sandbox, feature, duration, error
90
+ )
91
+
92
+ def on_feature_teardown(self, environment, sandbox, feature, duration, error):
93
+ self._record_call(
94
+ 'on_feature_teardown', environment, sandbox, feature, duration, error
95
+ )
96
+
97
+ def on_feature_setup_session(
98
+ self, environment, sandbox, feature, session_id, duration, error
99
+ ):
100
+ self._record_call(
101
+ 'on_feature_setup_session',
102
+ environment,
103
+ sandbox,
104
+ feature,
105
+ session_id,
106
+ duration,
107
+ error,
108
+ )
109
+
110
+ def on_feature_teardown_session(
111
+ self, environment, sandbox, feature, session_id, duration, error
112
+ ):
113
+ self._record_call(
114
+ 'on_feature_teardown_session',
115
+ environment,
116
+ sandbox,
117
+ feature,
118
+ session_id,
119
+ duration,
120
+ error,
121
+ )
122
+
123
+ def on_feature_housekeep(
124
+ self, environment, sandbox, feature, counter, duration, error, **kwargs
125
+ ):
126
+ self._record_call(
127
+ 'on_feature_housekeep',
128
+ environment,
129
+ sandbox,
130
+ feature,
131
+ counter,
132
+ duration,
133
+ error,
134
+ **kwargs,
135
+ )
136
+
137
+ def on_session_start(
138
+ self, environment, sandbox, session_id, duration, error
139
+ ):
140
+ self._record_call(
141
+ 'on_session_start', environment, sandbox, session_id, duration, error
142
+ )
143
+
144
+ def on_session_end(
145
+ self, environment, sandbox, session_id, duration, lifetime, error
146
+ ):
147
+ self._record_call(
148
+ 'on_session_end',
149
+ environment,
150
+ sandbox,
151
+ session_id,
152
+ duration,
153
+ lifetime,
154
+ error,
155
+ )
156
+
157
+ def on_sandbox_activity(
158
+ self,
159
+ name,
160
+ environment,
161
+ sandbox,
162
+ feature,
163
+ session_id,
164
+ duration,
165
+ error,
166
+ **kwargs,
167
+ ):
168
+ self._record_call(
169
+ 'on_sandbox_activity',
170
+ name,
171
+ environment,
172
+ sandbox,
173
+ feature,
174
+ session_id,
175
+ duration,
176
+ error,
177
+ **kwargs,
178
+ )
179
+
180
+
181
+ class EventHandlerChainTest(unittest.TestCase):
182
+
183
+ def test_chain(self):
184
+ handler1 = MockEventHandler()
185
+ handler2 = MockEventHandler()
186
+ chain_handler = chain.EventHandlerChain([handler1, handler2])
187
+
188
+ env = object()
189
+ sandbox = object()
190
+ feature = object()
191
+
192
+ chain_handler.on_environment_starting(env)
193
+ chain_handler.on_environment_shutting_down(env, 1.0)
194
+ chain_handler.on_environment_start(env, 2.0, None)
195
+ chain_handler.on_environment_housekeep(env, 1, 3.0, None, a=1)
196
+ chain_handler.on_environment_shutdown(env, 4.0, 5.0, None)
197
+ chain_handler.on_sandbox_start(env, sandbox, 6.0, None)
198
+ chain_handler.on_sandbox_status_change(env, sandbox, 'old', 'new', 7.0)
199
+ chain_handler.on_sandbox_shutdown(env, sandbox, 8.0, 9.0, None)
200
+ chain_handler.on_sandbox_housekeep(env, sandbox, 2, 10.0, None, b=2)
201
+ chain_handler.on_feature_setup(env, sandbox, feature, 11.0, None)
202
+ chain_handler.on_feature_teardown(env, sandbox, feature, 12.0, None)
203
+ chain_handler.on_feature_setup_session(
204
+ env, sandbox, feature, 's1', 13.0, None
205
+ )
206
+ chain_handler.on_feature_teardown_session(
207
+ env, sandbox, feature, 's1', 14.0, None
208
+ )
209
+ chain_handler.on_feature_housekeep(
210
+ env, sandbox, feature, 3, 15.0, None, c=3
211
+ )
212
+ chain_handler.on_session_start(env, sandbox, 's2', 16.0, None)
213
+ chain_handler.on_session_end(env, sandbox, 's2', 17.0, 18.0, None)
214
+ chain_handler.on_sandbox_activity(
215
+ 'act', env, sandbox, feature, 's2', 19.0, None, d=4
216
+ )
217
+
218
+ self.assertEqual(handler1.calls, handler2.calls)
219
+ self.assertEqual(
220
+ handler1.calls,
221
+ [
222
+ ('on_environment_starting', (env,), {}),
223
+ ('on_environment_shutting_down', (env, 1.0), {}),
224
+ ('on_environment_start', (env, 2.0, None), {}),
225
+ ('on_environment_housekeep', (env, 1, 3.0, None), {'a': 1}),
226
+ ('on_environment_shutdown', (env, 4.0, 5.0, None), {}),
227
+ ('on_sandbox_start', (env, sandbox, 6.0, None), {}),
228
+ ('on_sandbox_status_change', (env, sandbox, 'old', 'new', 7.0), {}),
229
+ ('on_sandbox_shutdown', (env, sandbox, 8.0, 9.0, None), {}),
230
+ ('on_sandbox_housekeep', (env, sandbox, 2, 10.0, None), {'b': 2}),
231
+ ('on_feature_setup', (env, sandbox, feature, 11.0, None), {}),
232
+ ('on_feature_teardown', (env, sandbox, feature, 12.0, None), {}),
233
+ (
234
+ 'on_feature_setup_session',
235
+ (env, sandbox, feature, 's1', 13.0, None),
236
+ {},
237
+ ),
238
+ (
239
+ 'on_feature_teardown_session',
240
+ (env, sandbox, feature, 's1', 14.0, None),
241
+ {},
242
+ ),
243
+ (
244
+ 'on_feature_housekeep',
245
+ (env, sandbox, feature, 3, 15.0, None),
246
+ {'c': 3},
247
+ ),
248
+ ('on_session_start', (env, sandbox, 's2', 16.0, None), {}),
249
+ ('on_session_end', (env, sandbox, 's2', 17.0, 18.0, None), {}),
250
+ (
251
+ 'on_sandbox_activity',
252
+ ('act', env, sandbox, feature, 's2', 19.0, None),
253
+ {'d': 4},
254
+ ),
255
+ ],
256
+ )
257
+
258
+ def test_add_remove(self):
259
+ handler1 = MockEventHandler()
260
+ handler2 = MockEventHandler()
261
+ chain_handler = chain.EventHandlerChain([handler1])
262
+ chain_handler.add(handler2)
263
+ env = object()
264
+ chain_handler.on_environment_starting(env)
265
+ self.assertEqual(handler1.calls, [('on_environment_starting', (env,), {})])
266
+ self.assertEqual(handler2.calls, [('on_environment_starting', (env,), {})])
267
+
268
+ chain_handler.remove(handler1)
269
+ chain_handler.on_environment_start(env, 1.0, None)
270
+ self.assertEqual(handler1.calls, [('on_environment_starting', (env,), {})])
271
+ self.assertEqual(
272
+ handler2.calls,
273
+ [
274
+ ('on_environment_starting', (env,), {}),
275
+ ('on_environment_start', (env, 1.0, None), {}),
276
+ ],
277
+ )
278
+
279
+
280
+ if __name__ == '__main__':
281
+ unittest.main()