77
88import asyncio
99from datetime import datetime
10- from yokedcache import YokedCache , cached , CacheConfig
10+
11+ from yokedcache import CacheConfig , YokedCache , cached
1112
1213
1314async def basic_cache_operations ():
1415 """Demonstrate basic cache operations."""
1516 print ("=== Basic Cache Operations ===" )
16-
17+
1718 # Initialize cache
1819 cache = YokedCache (redis_url = "redis://localhost:6379/0" )
19-
20+
2021 try :
2122 # Connect to Redis
2223 await cache .connect ()
23-
24+
2425 # Basic set and get
25- await cache .set ("user:123" , {"name" : "Alice" , "email" : "alice@example.com" }, ttl = 300 )
26+ await cache .set (
27+ "user:123" , {"name" : "Alice" , "email" : "alice@example.com" }, ttl = 300
28+ )
2629 user = await cache .get ("user:123" )
2730 print (f"Retrieved user: { user } " )
28-
31+
2932 # Set with tags for grouping
3033 await cache .set (
31- "user:124" ,
32- {"name" : "Bob" , "email" : "bob@example.com" },
34+ "user:124" ,
35+ {"name" : "Bob" , "email" : "bob@example.com" },
3336 ttl = 300 ,
34- tags = ["users" , "active" ]
37+ tags = ["users" , "active" ],
3538 )
36-
39+
3740 await cache .set (
38- "user:125" ,
39- {"name" : "Charlie" , "email" : "charlie@example.com" },
41+ "user:125" ,
42+ {"name" : "Charlie" , "email" : "charlie@example.com" },
4043 ttl = 300 ,
41- tags = ["users" , "inactive" ]
44+ tags = ["users" , "inactive" ],
4245 )
43-
46+
4447 # Check if key exists
4548 exists = await cache .exists ("user:123" )
4649 print (f"User 123 exists: { exists } " )
47-
50+
4851 # Get cache statistics
4952 stats = await cache .get_stats ()
5053 print (f"Cache hits: { stats .total_hits } , misses: { stats .total_misses } " )
5154 print (f"Hit rate: { stats .hit_rate :.2f} %" )
52-
55+
5356 finally :
5457 await cache .disconnect ()
5558
5659
5760async def tag_based_invalidation ():
5861 """Demonstrate tag-based cache invalidation."""
5962 print ("\n === Tag-Based Invalidation ===" )
60-
63+
6164 cache = YokedCache ()
62-
65+
6366 try :
6467 await cache .connect ()
65-
68+
6669 # Set multiple items with tags
67- await cache .set ("product:1" , {"name" : "Laptop" , "price" : 1000 }, tags = ["products" , "electronics" ])
68- await cache .set ("product:2" , {"name" : "Phone" , "price" : 500 }, tags = ["products" , "electronics" ])
69- await cache .set ("product:3" , {"name" : "Book" , "price" : 20 }, tags = ["products" , "books" ])
70-
70+ await cache .set (
71+ "product:1" ,
72+ {"name" : "Laptop" , "price" : 1000 },
73+ tags = ["products" , "electronics" ],
74+ )
75+ await cache .set (
76+ "product:2" ,
77+ {"name" : "Phone" , "price" : 500 },
78+ tags = ["products" , "electronics" ],
79+ )
80+ await cache .set (
81+ "product:3" , {"name" : "Book" , "price" : 20 }, tags = ["products" , "books" ]
82+ )
83+
7184 # Verify items exist
7285 print (f"Product 1: { await cache .get ('product:1' )} " )
7386 print (f"Product 2: { await cache .get ('product:2' )} " )
7487 print (f"Product 3: { await cache .get ('product:3' )} " )
75-
88+
7689 # Invalidate all electronics
7790 deleted_count = await cache .invalidate_tags (["electronics" ])
7891 print (f"Deleted { deleted_count } electronics items" )
79-
92+
8093 # Check what remains
8194 print (f"Product 1 after invalidation: { await cache .get ('product:1' )} " ) # None
8295 print (f"Product 2 after invalidation: { await cache .get ('product:2' )} " ) # None
83- print (f"Product 3 after invalidation: { await cache .get ('product:3' )} " ) # Still exists
84-
96+ print (
97+ f"Product 3 after invalidation: { await cache .get ('product:3' )} "
98+ ) # Still exists
99+
85100 finally :
86101 await cache .disconnect ()
87102
88103
89104async def pattern_based_invalidation ():
90105 """Demonstrate pattern-based cache invalidation."""
91106 print ("\n === Pattern-Based Invalidation ===" )
92-
107+
93108 cache = YokedCache ()
94-
109+
95110 try :
96111 await cache .connect ()
97-
112+
98113 # Set items with predictable key patterns
99114 await cache .set ("session:user:123" , {"login_time" : datetime .now ().isoformat ()})
100115 await cache .set ("session:user:124" , {"login_time" : datetime .now ().isoformat ()})
101116 await cache .set ("session:admin:125" , {"login_time" : datetime .now ().isoformat ()})
102117 await cache .set ("config:app:theme" , {"theme" : "dark" })
103-
118+
104119 # Invalidate all user sessions
105120 deleted_count = await cache .invalidate_pattern ("session:user:*" )
106121 print (f"Deleted { deleted_count } user session keys" )
107-
122+
108123 # Check remaining keys
109124 print (f"User 123 session: { await cache .get ('session:user:123' )} " ) # None
110- print (f"Admin 125 session: { await cache .get ('session:admin:125' )} " ) # Still exists
125+ print (
126+ f"Admin 125 session: { await cache .get ('session:admin:125' )} "
127+ ) # Still exists
111128 print (f"App config: { await cache .get ('config:app:theme' )} " ) # Still exists
112-
129+
113130 finally :
114131 await cache .disconnect ()
115132
116133
117134async def fuzzy_search_example ():
118135 """Demonstrate fuzzy search capabilities."""
119136 print ("\n === Fuzzy Search ===" )
120-
137+
121138 # Enable fuzzy search in config
122139 config = CacheConfig (enable_fuzzy = True , fuzzy_threshold = 70 )
123140 cache = YokedCache (config = config )
124-
141+
125142 try :
126143 await cache .connect ()
127-
144+
128145 # Set items with searchable content
129- await cache .set ("user:alice:profile" , {"name" : "Alice Johnson" , "role" : "developer" })
146+ await cache .set (
147+ "user:alice:profile" , {"name" : "Alice Johnson" , "role" : "developer" }
148+ )
130149 await cache .set ("user:bob:profile" , {"name" : "Bob Smith" , "role" : "designer" })
131- await cache .set ("user:charlie:profile" , {"name" : "Charlie Brown" , "role" : "manager" })
132- await cache .set ("product:laptop:details" , {"name" : "Gaming Laptop" , "category" : "electronics" })
133-
150+ await cache .set (
151+ "user:charlie:profile" , {"name" : "Charlie Brown" , "role" : "manager" }
152+ )
153+ await cache .set (
154+ "product:laptop:details" ,
155+ {"name" : "Gaming Laptop" , "category" : "electronics" },
156+ )
157+
134158 # Perform fuzzy search
135159 results = await cache .fuzzy_search ("alice" , threshold = 70 , max_results = 5 )
136-
160+
137161 print (f"Fuzzy search results for 'alice':" )
138162 for result in results :
139163 print (f" Key: { result .key } , Score: { result .score } %, Value: { result .value } " )
140-
164+
141165 # Search for profiles
142166 profile_results = await cache .fuzzy_search ("profile" , threshold = 60 )
143167 print (f"\n Fuzzy search results for 'profile':" )
144168 for result in profile_results :
145169 print (f" Key: { result .key } , Score: { result .score } %" )
146-
170+
147171 finally :
148172 await cache .disconnect ()
149173
@@ -152,43 +176,43 @@ async def fuzzy_search_example():
152176async def expensive_database_operation (query_param ):
153177 """Example of using the @cached decorator."""
154178 print (f"Executing expensive operation with param: { query_param } " )
155-
179+
156180 # Simulate expensive database query
157181 await asyncio .sleep (1 ) # Simulated delay
158-
182+
159183 return {
160184 "param" : query_param ,
161185 "result" : f"processed_{ query_param } " ,
162- "timestamp" : datetime .now ().isoformat ()
186+ "timestamp" : datetime .now ().isoformat (),
163187 }
164188
165189
166190async def decorator_example ():
167191 """Demonstrate using the @cached decorator."""
168192 print ("\n === Decorator Usage ===" )
169-
193+
170194 # First call - will execute function
171195 start_time = datetime .now ()
172196 result1 = await expensive_database_operation ("test_query" )
173197 first_duration = (datetime .now () - start_time ).total_seconds ()
174198 print (f"First call result: { result1 } " )
175199 print (f"First call duration: { first_duration :.3f} seconds" )
176-
200+
177201 # Second call - will use cache
178202 start_time = datetime .now ()
179203 result2 = await expensive_database_operation ("test_query" )
180204 second_duration = (datetime .now () - start_time ).total_seconds ()
181205 print (f"Second call result: { result2 } " )
182206 print (f"Second call duration: { second_duration :.3f} seconds" )
183-
207+
184208 # Should be much faster the second time
185209 print (f"Speed improvement: { first_duration / second_duration :.1f} x faster" )
186210
187211
188212async def configuration_example ():
189213 """Demonstrate different configuration options."""
190214 print ("\n === Configuration Example ===" )
191-
215+
192216 # Create custom configuration
193217 config = CacheConfig (
194218 redis_url = "redis://localhost:6379/1" , # Different database
@@ -197,26 +221,26 @@ async def configuration_example():
197221 enable_fuzzy = True ,
198222 fuzzy_threshold = 85 ,
199223 max_connections = 20 ,
200- log_level = "DEBUG"
224+ log_level = "DEBUG" ,
201225 )
202-
226+
203227 cache = YokedCache (config = config )
204-
228+
205229 try :
206230 await cache .connect ()
207-
231+
208232 # Set value with custom config
209233 await cache .set ("custom:config:test" , {"configured" : True })
210-
234+
211235 # Get configuration details
212236 print (f"Key prefix: { cache .config .key_prefix } " )
213237 print (f"Default TTL: { cache .config .default_ttl } " )
214238 print (f"Fuzzy enabled: { cache .config .enable_fuzzy } " )
215-
239+
216240 # Verify value was stored
217241 value = await cache .get ("custom:config:test" )
218242 print (f"Retrieved value: { value } " )
219-
243+
220244 finally :
221245 await cache .disconnect ()
222246
@@ -225,14 +249,14 @@ async def main():
225249 """Run all examples."""
226250 print ("YokedCache Usage Examples" )
227251 print ("=" * 50 )
228-
252+
229253 await basic_cache_operations ()
230254 await tag_based_invalidation ()
231255 await pattern_based_invalidation ()
232256 await fuzzy_search_example ()
233257 await decorator_example ()
234258 await configuration_example ()
235-
259+
236260 print ("\n " + "=" * 50 )
237261 print ("All examples completed!" )
238262
0 commit comments