flagrant-client 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-09-11-21-40-01.md +98 -0
- flagrant_client-0.2.0/.agent-shell/transcripts/2026-10-01-22-10-28.md +264 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/PKG-INFO +2 -2
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/README.md +1 -1
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/pyproject.toml +1 -1
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/__init__.py +2 -2
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/cache.py +2 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/client.py +2 -2
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/uv.lock +263 -263
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-08-11-10-19-43.md +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-08-18-10-59-01.md +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-08-19-00-02-53.md +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-08-26-23-27-24.md +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.gitignore +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/.python-version +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/LICENSE +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/proto/features.proto +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/grpc_transport.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/http_transport.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/models.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/proto/__init__.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/proto/features_pb2.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/proto/features_pb2.pyi +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/proto/features_pb2_grpc.py +0 -0
- {flagrant_client-0.1.0 → flagrant_client-0.2.0}/src/flagrant/transport.py +0 -0
{flagrant_client-0.1.0 → flagrant_client-0.2.0}/.agent-shell/transcripts/2026-09-11-21-40-01.md
RENAMED
|
@@ -1287,3 +1287,101 @@ SOFTWARE.
|
|
|
1287
1287
|
|
|
1288
1288
|
I should check whether the hatchling version being used supports the PEP 639 SPDX license string format, since older versions might not handle `license = "MIT"` correctly. Let me just confirm the build works with this setup.
|
|
1289
1289
|
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
### Tool Call [completed]: uv build 2>&1 | tail -30
|
|
1293
|
+
|
|
1294
|
+
**Tool:** execute
|
|
1295
|
+
**Timestamp:** 2026-09-11 22:40:17
|
|
1296
|
+
**Command:** uv build 2>&1 | tail -30
|
|
1297
|
+
|
|
1298
|
+
````
|
|
1299
|
+
```console
|
|
1300
|
+
Building source distribution...
|
|
1301
|
+
Building wheel from source distribution...
|
|
1302
|
+
Successfully built dist/flagrant_client-0.1.0.tar.gz
|
|
1303
|
+
Successfully built dist/flagrant_client-0.1.0-py3-none-any.whl
|
|
1304
|
+
```
|
|
1305
|
+
````
|
|
1306
|
+
|
|
1307
|
+
## Agent (2026-09-11 22:40:19)
|
|
1308
|
+
|
|
1309
|
+
Build succeeds. Updated `pyproject.toml` with description, `license = "MIT"`, GitHub homepage/repository URLs, and the two classifiers, and added a `LICENSE` (MIT, Michal Buczko) file. Verified with `uv build` — both sdist and wheel build cleanly.
|
|
1310
|
+
|
|
1311
|
+
You're set to publish with `uv publish` (needs a PyPI token via `UV_PUBLISH_TOKEN` or `--token`).
|
|
1312
|
+
|
|
1313
|
+
## User (2026-09-11 22:56:12)
|
|
1314
|
+
|
|
1315
|
+
how to remove a history in fish shell? I'd like to remove the recent entry.
|
|
1316
|
+
|
|
1317
|
+
## Agent's Thoughts (2026-09-11 22:56:18)
|
|
1318
|
+
|
|
1319
|
+
This is about fish shell history rather than the repo itself. Fish stores history in ~/.local/share/fish/fish_history, and I recall the `history delete` command can remove entries by exact match, so I need to find the right syntax to delete just the most recent one.
|
|
1320
|
+
|
|
1321
|
+
My plan: capture the most recent command with `history --max 1`, store it in a variable, then pass that to `history delete --exact --` to remove it precisely.
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
### Tool Call [completed]: fish -c 'history --help' 2>&1 | head -40
|
|
1326
|
+
|
|
1327
|
+
**Tool:** execute
|
|
1328
|
+
**Timestamp:** 2026-09-11 22:56:27
|
|
1329
|
+
**Command:** fish -c 'history --help' 2>&1 | head -40
|
|
1330
|
+
|
|
1331
|
+
````
|
|
1332
|
+
```console
|
|
1333
|
+
HISTORY(1) fish-shell HISTORY(1)
|
|
1334
|
+
|
|
1335
|
+
NNAAMMEE
|
|
1336
|
+
history - show and manipulate command history
|
|
1337
|
+
|
|
1338
|
+
SSYYNNOOPPSSIISS
|
|
1339
|
+
hhiissttoorryy [sseeaarrcchh] [----sshhooww--ttiimmee] [----ccaassee--sseennssiittiivvee]
|
|
1340
|
+
[----eexxaacctt | ----pprreeffiixx | ----ccoonnttaaiinnss] [----mmaaxx _N] [----nnuullll] [----rreevveerrssee]
|
|
1341
|
+
[_S_E_A_R_C_H___S_T_R_I_N_G ...]
|
|
1342
|
+
hhiissttoorryy ddeelleettee [----ccaassee--sseennssiittiivvee]
|
|
1343
|
+
[----eexxaacctt | ----pprreeffiixx | ----ccoonnttaaiinnss] _S_E_A_R_C_H___S_T_R_I_N_G ...
|
|
1344
|
+
hhiissttoorryy mmeerrggee
|
|
1345
|
+
hhiissttoorryy ssaavvee
|
|
1346
|
+
hhiissttoorryy cclleeaarr
|
|
1347
|
+
hhiissttoorryy cclleeaarr--sseessssiioonn
|
|
1348
|
+
hhiissttoorryy aappppeenndd _C_O_M_M_A_N_D ...
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
DDEESSCCRRIIPPTTIIOONN
|
|
1352
|
+
hhiissttoorryy is used to search, delete, and otherwise manipulate the history
|
|
1353
|
+
of interactive commands <#history-search>.
|
|
1354
|
+
|
|
1355
|
+
The following operations (sub-commands) are available:
|
|
1356
|
+
|
|
1357
|
+
sseeaarrcchh Returns history items matching the search string. If no search
|
|
1358
|
+
string is provided it returns all history items. This is the
|
|
1359
|
+
default operation if no other operation is specified. You only
|
|
1360
|
+
have to explicitly say hhiissttoorryy sseeaarrcchh if you wish to search for
|
|
1361
|
+
one of the subcommands. The ----ccoonnttaaiinnss search option will be
|
|
1362
|
+
used if you don't specify a different search option. Entries are
|
|
1363
|
+
ordered newest to oldest unless you use the ----rreevveerrssee flag. If
|
|
1364
|
+
stdout is attached to a tty the output will be piped through
|
|
1365
|
+
your pager by the history function. The history builtin writes
|
|
1366
|
+
the results to stdout.
|
|
1367
|
+
|
|
1368
|
+
ddeelleettee Deletes history items. The ----ccoonnttaaiinnss search option will be used
|
|
1369
|
+
if you don't specify a different search option. If you don't
|
|
1370
|
+
specify ----eexxaacctt a prompt will be displayed before any items are
|
|
1371
|
+
deleted asking you which entries are to be deleted. You can
|
|
1372
|
+
enter the word "all" to delete all matching entries. You can
|
|
1373
|
+
```
|
|
1374
|
+
````
|
|
1375
|
+
|
|
1376
|
+
## Agent (2026-09-11 22:56:29)
|
|
1377
|
+
|
|
1378
|
+
To delete just the most recent history entry in fish:
|
|
1379
|
+
|
|
1380
|
+
```fish
|
|
1381
|
+
history delete --exact --case-sensitive -- (history --max 1)
|
|
1382
|
+
```
|
|
1383
|
+
|
|
1384
|
+
`history --max 1` grabs the last entry's exact text, and `history delete --exact` removes only that exact match (without `--exact` it does a `--contains` match and prompts you interactively). Run `history save` afterward if you want the deletion flushed to disk immediately (fish normally does this on shell exit anyway).
|
|
1385
|
+
|
|
1386
|
+
If you'd rather do it interactively: just run `history delete <part of the command>` — fish will show matching entries and let you type `all` or pick which to remove.
|
|
1387
|
+
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Agent Shell Transcript
|
|
2
|
+
|
|
3
|
+
**Agent:** Claude
|
|
4
|
+
**Started:** 2026-10-01 22:10:40
|
|
5
|
+
**Working Directory:** /Users/michal/workspace/python/flagrant-client/
|
|
6
|
+
**Session ID:** a52ab1c2-8ea5-4e3d-97db-b9e80551c806
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## User (2026-10-01 22:10:40)
|
|
11
|
+
|
|
12
|
+
rename it to FlagrantOpts
|
|
13
|
+
|
|
14
|
+
src/flagrant/client.py:12-12
|
|
15
|
+
|
|
16
|
+
class FlagsmithOpts:
|
|
17
|
+
|
|
18
|
+
## Agent's Thoughts (2026-10-01 22:10:42)
|
|
19
|
+
|
|
20
|
+
I need to rename FlagsmithOpts to FlagrantOpts in src/flagrant/client.py, so let me check that file first.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Tool Call [completed]: Read src/flagrant/client.py
|
|
25
|
+
|
|
26
|
+
**Tool:** read
|
|
27
|
+
**Timestamp:** 2026-10-01 22:10:42
|
|
28
|
+
**Parameters:**
|
|
29
|
+
file_path: /Users/michal/workspace/python/flagrant-client/src/flagrant/client.py
|
|
30
|
+
|
|
31
|
+
````
|
|
32
|
+
```
|
|
33
|
+
1 from collections.abc import Callable
|
|
34
|
+
2 from dataclasses import dataclass
|
|
35
|
+
3 from typing import Any
|
|
36
|
+
4
|
|
37
|
+
5 from flagrant.cache import LRUCache
|
|
38
|
+
6 from flagrant.models import Feature
|
|
39
|
+
7 from flagrant.transport import Transport, TransientError
|
|
40
|
+
8
|
|
41
|
+
9 DefaultFlagHandler = Callable[[str, str], list[Feature] | None]
|
|
42
|
+
10
|
|
43
|
+
11 @dataclass(frozen=True)
|
|
44
|
+
12 class FlagsmithOpts:
|
|
45
|
+
13 cache_ttl: float | None = None
|
|
46
|
+
14 cache_size: int | None = None
|
|
47
|
+
15
|
|
48
|
+
16
|
|
49
|
+
17 class FlagrantClient:
|
|
50
|
+
18 def __init__(
|
|
51
|
+
19 self,
|
|
52
|
+
20 project: str,
|
|
53
|
+
21 transport: Transport,
|
|
54
|
+
22 *,
|
|
55
|
+
23 default_handler: DefaultFlagHandler | None = None,
|
|
56
|
+
24 opts: FlagsmithOpts = FlagsmithOpts()
|
|
57
|
+
25 ) -> None:
|
|
58
|
+
26 self.project = project
|
|
59
|
+
27 self.transport = transport
|
|
60
|
+
28 self.opts = opts
|
|
61
|
+
29 self.default_handler = default_handler
|
|
62
|
+
30
|
|
63
|
+
31 self._cache: LRUCache[tuple[str, str], list[Feature]] | None = (
|
|
64
|
+
32 LRUCache(max_size=opts.cache_size, ttl=opts.cache_ttl)
|
|
65
|
+
33 if opts.cache_size
|
|
66
|
+
34 else None
|
|
67
|
+
35 )
|
|
68
|
+
36
|
|
69
|
+
37 def get_features(self, environment: str, identity: str) -> list[Feature] | None:
|
|
70
|
+
38 key = (environment, identity)
|
|
71
|
+
39 if self._cache is not None:
|
|
72
|
+
40 if cached := self._cache.get(key):
|
|
73
|
+
41 return cached
|
|
74
|
+
42
|
|
75
|
+
43 try:
|
|
76
|
+
44 features = self.transport.fetch(self.project, environment, identity)
|
|
77
|
+
45 except TransientError:
|
|
78
|
+
46 if self._cache is not None and (stale := self._cache.get_stale(key)) is not None:
|
|
79
|
+
47 return stale
|
|
80
|
+
48 if self.default_handler is None:
|
|
81
|
+
49 raise
|
|
82
|
+
50 return self.default_handler(environment, identity)
|
|
83
|
+
51
|
|
84
|
+
52 if self._cache is not None:
|
|
85
|
+
53 self._cache.set(key, features)
|
|
86
|
+
54
|
|
87
|
+
55 return features
|
|
88
|
+
56
|
|
89
|
+
57 def close(self) -> None:
|
|
90
|
+
58 self.transport.close()
|
|
91
|
+
59
|
|
92
|
+
60 def __enter__(self) -> "FlagrantClient":
|
|
93
|
+
61 return self
|
|
94
|
+
62
|
|
95
|
+
63 def __exit__(self, *_args: Any) -> None:
|
|
96
|
+
64 self.close()
|
|
97
|
+
```
|
|
98
|
+
````
|
|
99
|
+
|
|
100
|
+
## Agent (2026-10-01 22:10:43)
|
|
101
|
+
|
|
102
|
+
Let me check for other usages of `FlagsmithOpts` across the repo before renaming.
|
|
103
|
+
|
|
104
|
+
### Tool Call [completed]: grep -rn "FlagsmithOpts" /Users/michal/workspace/python/flagrant-client --include="*.py"
|
|
105
|
+
|
|
106
|
+
**Tool:** execute
|
|
107
|
+
**Timestamp:** 2026-10-01 22:10:44
|
|
108
|
+
**Description:** Search for other usages of FlagsmithOpts
|
|
109
|
+
**Command:** grep -rn "FlagsmithOpts" /Users/michal/workspace/python/flagrant-client --include="*.py"
|
|
110
|
+
|
|
111
|
+
````
|
|
112
|
+
```console
|
|
113
|
+
/Users/michal/workspace/python/flagrant-client/src/flagrant/client.py:12:class FlagsmithOpts:
|
|
114
|
+
/Users/michal/workspace/python/flagrant-client/src/flagrant/client.py:24: opts: FlagsmithOpts = FlagsmithOpts()
|
|
115
|
+
/Users/michal/workspace/python/flagrant-client/src/flagrant/__init__.py:1:from flagrant.client import FlagrantClient, FlagsmithOpts
|
|
116
|
+
/Users/michal/workspace/python/flagrant-client/src/flagrant/__init__.py:8: "FlagsmithOpts",
|
|
117
|
+
```
|
|
118
|
+
````
|
|
119
|
+
|
|
120
|
+
## Agent (2026-10-01 22:10:45)
|
|
121
|
+
|
|
122
|
+
Only two files reference it. Renaming both.
|
|
123
|
+
|
|
124
|
+
### Tool Call [completed]: Edit src/flagrant/client.py
|
|
125
|
+
|
|
126
|
+
**Tool:** edit
|
|
127
|
+
**Timestamp:** 2026-10-01 22:10:51
|
|
128
|
+
**Parameters:**
|
|
129
|
+
file_path: /Users/michal/workspace/python/flagrant-client/src/flagrant/client.py
|
|
130
|
+
old_string: class FlagsmithOpts:
|
|
131
|
+
cache_ttl: float | None = None
|
|
132
|
+
cache_size: int | None = None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class FlagrantClient:
|
|
136
|
+
def __init__(
|
|
137
|
+
self,
|
|
138
|
+
project: str,
|
|
139
|
+
transport: Transport,
|
|
140
|
+
*,
|
|
141
|
+
default_handler: DefaultFlagHandler | None = None,
|
|
142
|
+
opts: FlagsmithOpts = FlagsmithOpts()
|
|
143
|
+
new_string: class FlagrantOpts:
|
|
144
|
+
cache_ttl: float | None = None
|
|
145
|
+
cache_size: int | None = None
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class FlagrantClient:
|
|
149
|
+
def __init__(
|
|
150
|
+
self,
|
|
151
|
+
project: str,
|
|
152
|
+
transport: Transport,
|
|
153
|
+
*,
|
|
154
|
+
default_handler: DefaultFlagHandler | None = None,
|
|
155
|
+
opts: FlagrantOpts = FlagrantOpts()
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
╭────────────────────────╮
|
|
159
|
+
│ src/flagrant/client.py │
|
|
160
|
+
╰────────────────────────╯
|
|
161
|
+
|
|
162
|
+
@@ -1,6 +1,6 @@
|
|
163
|
+
DefaultFlagHandler = Callable[[str, str], list[Feature] | None]
|
|
164
|
+
|
|
165
|
+
@dataclass(frozen=True)
|
|
166
|
+
-class FlagsmithOpts:
|
|
167
|
+
+class FlagrantOpts:
|
|
168
|
+
cache_ttl: float | None = None
|
|
169
|
+
cache_size: int | None = None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
╭────────────────────────╮
|
|
173
|
+
│ src/flagrant/client.py │
|
|
174
|
+
╰────────────────────────╯
|
|
175
|
+
|
|
176
|
+
@@ -1,7 +1,7 @@
|
|
177
|
+
transport: Transport,
|
|
178
|
+
*,
|
|
179
|
+
default_handler: DefaultFlagHandler | None = None,
|
|
180
|
+
- opts: FlagsmithOpts = FlagsmithOpts()
|
|
181
|
+
+ opts: FlagrantOpts = FlagrantOpts()
|
|
182
|
+
) -> None:
|
|
183
|
+
self.project = project
|
|
184
|
+
self.transport = transport
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
### Tool Call [completed]: Read src/flagrant/__init__.py
|
|
190
|
+
|
|
191
|
+
**Tool:** read
|
|
192
|
+
**Timestamp:** 2026-10-01 22:10:52
|
|
193
|
+
**Parameters:**
|
|
194
|
+
file_path: /Users/michal/workspace/python/flagrant-client/src/flagrant/__init__.py
|
|
195
|
+
|
|
196
|
+
````
|
|
197
|
+
```
|
|
198
|
+
1 from flagrant.client import FlagrantClient, FlagsmithOpts
|
|
199
|
+
2 from flagrant.grpc_transport import GrpcTransport
|
|
200
|
+
3 from flagrant.http_transport import HttpTransport
|
|
201
|
+
4 from flagrant.transport import PermanentError, Transport, TransientError
|
|
202
|
+
5
|
|
203
|
+
6 __all__ = [
|
|
204
|
+
7 "FlagrantClient",
|
|
205
|
+
8 "FlagsmithOpts",
|
|
206
|
+
9 "GrpcTransport",
|
|
207
|
+
10 "HttpTransport",
|
|
208
|
+
11 "PermanentError",
|
|
209
|
+
12 "Transport",
|
|
210
|
+
13 "TransientError",
|
|
211
|
+
14 ]
|
|
212
|
+
```
|
|
213
|
+
````
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
### Tool Call [completed]: Edit src/flagrant/__init__.py
|
|
217
|
+
|
|
218
|
+
**Tool:** edit
|
|
219
|
+
**Timestamp:** 2026-10-01 22:10:59
|
|
220
|
+
**Parameters:**
|
|
221
|
+
file_path: /Users/michal/workspace/python/flagrant-client/src/flagrant/__init__.py
|
|
222
|
+
old_string: from flagrant.client import FlagrantClient, FlagsmithOpts
|
|
223
|
+
from flagrant.grpc_transport import GrpcTransport
|
|
224
|
+
from flagrant.http_transport import HttpTransport
|
|
225
|
+
from flagrant.transport import PermanentError, Transport, TransientError
|
|
226
|
+
|
|
227
|
+
__all__ = [
|
|
228
|
+
"FlagrantClient",
|
|
229
|
+
"FlagsmithOpts",
|
|
230
|
+
new_string: from flagrant.client import FlagrantClient, FlagrantOpts
|
|
231
|
+
from flagrant.grpc_transport import GrpcTransport
|
|
232
|
+
from flagrant.http_transport import HttpTransport
|
|
233
|
+
from flagrant.transport import PermanentError, Transport, TransientError
|
|
234
|
+
|
|
235
|
+
__all__ = [
|
|
236
|
+
"FlagrantClient",
|
|
237
|
+
"FlagrantOpts",
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
╭──────────────────────────╮
|
|
241
|
+
│ src/flagrant/__init__.py │
|
|
242
|
+
╰──────────────────────────╯
|
|
243
|
+
|
|
244
|
+
@@ -1,11 +1,11 @@
|
|
245
|
+
-from flagrant.client import FlagrantClient, FlagsmithOpts
|
|
246
|
+
+from flagrant.client import FlagrantClient, FlagrantOpts
|
|
247
|
+
from flagrant.grpc_transport import GrpcTransport
|
|
248
|
+
from flagrant.http_transport import HttpTransport
|
|
249
|
+
from flagrant.transport import PermanentError, Transport, TransientError
|
|
250
|
+
|
|
251
|
+
__all__ = [
|
|
252
|
+
"FlagrantClient",
|
|
253
|
+
- "FlagsmithOpts",
|
|
254
|
+
+ "FlagrantOpts",
|
|
255
|
+
"GrpcTransport",
|
|
256
|
+
"HttpTransport",
|
|
257
|
+
"PermanentError",
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Agent (2026-10-01 22:10:59)
|
|
262
|
+
|
|
263
|
+
Done — renamed `FlagsmithOpts` → `FlagrantOpts` in `client.py:12,24` and `__init__.py:1,8`.
|
|
264
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: flagrant-client
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: A python client for Flagrant feature-flagging API
|
|
5
5
|
Project-URL: Homepage, https://github.com/mbuczko/flagrant-client-python
|
|
6
6
|
Project-URL: Repository, https://github.com/mbuczko/flagrant-client-python
|
|
@@ -39,7 +39,7 @@ This split lets `FlagrantClient.get_features` react differently depending on whe
|
|
|
39
39
|
|
|
40
40
|
## Caching and fallback
|
|
41
41
|
|
|
42
|
-
`FlagrantClient` optionally wraps fetches in an `LRUCache` (per `(environment, identity)` key), configured via `
|
|
42
|
+
`FlagrantClient` optionally wraps fetches in an `LRUCache` (per `(environment, identity)` key), configured via `FlagrantOpts(cache_size=..., cache_ttl=...)`. On a `TransientError`, the client tries a stale cache entry before falling back to a user-supplied `default_handler`, and only re-raises if neither is available.
|
|
43
43
|
|
|
44
44
|
## Testing in IPython
|
|
45
45
|
|
|
@@ -21,7 +21,7 @@ This split lets `FlagrantClient.get_features` react differently depending on whe
|
|
|
21
21
|
|
|
22
22
|
## Caching and fallback
|
|
23
23
|
|
|
24
|
-
`FlagrantClient` optionally wraps fetches in an `LRUCache` (per `(environment, identity)` key), configured via `
|
|
24
|
+
`FlagrantClient` optionally wraps fetches in an `LRUCache` (per `(environment, identity)` key), configured via `FlagrantOpts(cache_size=..., cache_ttl=...)`. On a `TransientError`, the client tries a stale cache entry before falling back to a user-supplied `default_handler`, and only re-raises if neither is available.
|
|
25
25
|
|
|
26
26
|
## Testing in IPython
|
|
27
27
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from flagrant.client import FlagrantClient,
|
|
1
|
+
from flagrant.client import FlagrantClient, FlagrantOpts
|
|
2
2
|
from flagrant.grpc_transport import GrpcTransport
|
|
3
3
|
from flagrant.http_transport import HttpTransport
|
|
4
4
|
from flagrant.transport import PermanentError, Transport, TransientError
|
|
5
5
|
|
|
6
6
|
__all__ = [
|
|
7
7
|
"FlagrantClient",
|
|
8
|
-
"
|
|
8
|
+
"FlagrantOpts",
|
|
9
9
|
"GrpcTransport",
|
|
10
10
|
"HttpTransport",
|
|
11
11
|
"PermanentError",
|
|
@@ -9,7 +9,7 @@ from flagrant.transport import Transport, TransientError
|
|
|
9
9
|
DefaultFlagHandler = Callable[[str, str], list[Feature] | None]
|
|
10
10
|
|
|
11
11
|
@dataclass(frozen=True)
|
|
12
|
-
class
|
|
12
|
+
class FlagrantOpts:
|
|
13
13
|
cache_ttl: float | None = None
|
|
14
14
|
cache_size: int | None = None
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@ class FlagrantClient:
|
|
|
21
21
|
transport: Transport,
|
|
22
22
|
*,
|
|
23
23
|
default_handler: DefaultFlagHandler | None = None,
|
|
24
|
-
opts:
|
|
24
|
+
opts: FlagrantOpts = FlagrantOpts()
|
|
25
25
|
) -> None:
|
|
26
26
|
self.project = project
|
|
27
27
|
self.transport = transport
|