@@ -140,13 +140,13 @@ def test_http_request_matching(mocker):
140140 users_policy .matches .side_effect = HttpRequestMatcher (
141141 url = "http://domain/api/users" , method = "GET"
142142 )
143- users_policy .get_cost .return_value = 1
143+ users_policy .get_weight .return_value = 1
144144 groups_policy .matches .side_effect = HttpRequestMatcher (
145145 url = "http://domain/api/groups" , method = "POST"
146146 )
147- groups_policy .get_cost .return_value = 1
147+ groups_policy .get_weight .return_value = 1
148148 root_policy .matches .side_effect = HttpRequestMatcher (method = "GET" )
149- root_policy .get_cost .return_value = 1
149+ root_policy .get_weight .return_value = 1
150150 api_budget = APIBudget (
151151 policies = [
152152 users_policy ,
@@ -363,64 +363,64 @@ def test_with_cache(self, mocker, requests_mock):
363363 assert MovingWindowCallRatePolicy .try_acquire .call_count == 1
364364
365365
366- class TestCostBasedRateLimiting :
367- """Tests for cost -based rate limiting where different endpoints consume different amounts from a shared budget."""
366+ class TestWeightBasedRateLimiting :
367+ """Tests for weight -based rate limiting where different endpoints consume different amounts from a shared budget."""
368368
369- def test_matcher_cost_default_none (self ):
370- """HttpRequestRegexMatcher cost defaults to None when not specified."""
369+ def test_matcher_weight_default_none (self ):
370+ """HttpRequestRegexMatcher weight defaults to None when not specified."""
371371 matcher = HttpRequestRegexMatcher (url_path_pattern = r"/api/test" )
372- assert matcher .cost is None
372+ assert matcher .weight is None
373373
374- def test_matcher_cost_is_stored (self ):
375- """HttpRequestRegexMatcher stores the cost value when provided."""
376- matcher = HttpRequestRegexMatcher (url_path_pattern = r"/api/test" , cost = 60 )
377- assert matcher .cost == 60
374+ def test_matcher_weight_is_stored (self ):
375+ """HttpRequestRegexMatcher stores the weight value when provided."""
376+ matcher = HttpRequestRegexMatcher (url_path_pattern = r"/api/test" , weight = 60 )
377+ assert matcher .weight == 60
378378
379- def test_policy_get_cost_returns_matcher_cost (self ):
380- """BaseCallRatePolicy.get_cost returns cost from the matching matcher."""
379+ def test_policy_get_weight_returns_matcher_weight (self ):
380+ """BaseCallRatePolicy.get_weight returns weight from the matching matcher."""
381381 policy = MovingWindowCallRatePolicy (
382- matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/expensive" , cost = 120 )],
382+ matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/expensive" , weight = 120 )],
383383 rates = [Rate (1000 , timedelta (hours = 1 ))],
384384 )
385385 req = Request ("GET" , "https://example.com/api/expensive" )
386- assert policy .get_cost (req ) == 120
386+ assert policy .get_weight (req ) == 120
387387
388- def test_policy_get_cost_defaults_to_1 (self ):
389- """BaseCallRatePolicy.get_cost returns 1 when no matcher has a cost set."""
388+ def test_policy_get_weight_defaults_to_1 (self ):
389+ """BaseCallRatePolicy.get_weight returns 1 when no matcher has a weight set."""
390390 policy = MovingWindowCallRatePolicy (
391391 matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/default" )],
392392 rates = [Rate (1000 , timedelta (hours = 1 ))],
393393 )
394394 req = Request ("GET" , "https://example.com/api/default" )
395- assert policy .get_cost (req ) == 1
395+ assert policy .get_weight (req ) == 1
396396
397- def test_policy_get_cost_no_matching_matcher (self ):
398- """BaseCallRatePolicy.get_cost returns 1 when no matcher matches the request."""
397+ def test_policy_get_weight_no_matching_matcher (self ):
398+ """BaseCallRatePolicy.get_weight returns 1 when no matcher matches the request."""
399399 policy = MovingWindowCallRatePolicy (
400- matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/other" , cost = 50 )],
400+ matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/other" , weight = 50 )],
401401 rates = [Rate (1000 , timedelta (hours = 1 ))],
402402 )
403403 req = Request ("GET" , "https://example.com/api/unmatched" )
404- assert policy .get_cost (req ) == 1
404+ assert policy .get_weight (req ) == 1
405405
406- def test_api_budget_uses_cost_as_weight (self ):
407- """APIBudget._do_acquire passes the matcher's cost as weight to try_acquire."""
406+ def test_api_budget_uses_weight (self ):
407+ """APIBudget._do_acquire passes the matcher's weight to try_acquire."""
408408 policy = MovingWindowCallRatePolicy (
409- matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/heavy" , cost = 10 )],
409+ matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/heavy" , weight = 10 )],
410410 rates = [Rate (100 , timedelta (hours = 1 ))],
411411 )
412412 budget = APIBudget (policies = [policy ])
413413
414- # Make requests — each costs 10 from the budget of 100
414+ # Make requests — each weighs 10 from the budget of 100
415415 for i in range (10 ):
416416 budget .acquire_call (Request ("GET" , "https://example.com/api/heavy" ), block = False )
417417
418418 # The 11th request should exceed the budget (10 * 10 = 100, one more = 110 > 100)
419419 with pytest .raises (CallRateLimitHit ):
420420 budget .acquire_call (Request ("GET" , "https://example.com/api/heavy" ), block = False )
421421
422- def test_cost_1_backward_compatible (self ):
423- """When cost is not set, behavior is identical to the old hardcoded weight=1."""
422+ def test_weight_1_backward_compatible (self ):
423+ """When weight is not set, behavior is identical to the old hardcoded weight=1."""
424424 policy = MovingWindowCallRatePolicy (
425425 matchers = [HttpRequestRegexMatcher (url_path_pattern = r"/api/normal" )],
426426 rates = [Rate (5 , timedelta (hours = 1 ))],
@@ -433,19 +433,19 @@ def test_cost_1_backward_compatible(self):
433433 with pytest .raises (CallRateLimitHit ):
434434 budget .acquire_call (Request ("GET" , "https://example.com/api/normal" ), block = False )
435435
436- def test_shared_budget_different_costs (self ):
437- """Multiple matchers with different costs sharing one policy correctly consume the shared budget."""
436+ def test_shared_budget_different_weights (self ):
437+ """Multiple matchers with different weights sharing one policy correctly consume the shared budget."""
438438 # Shared policy matches both endpoints via regex
439439 policy = MovingWindowCallRatePolicy (
440440 matchers = [
441- HttpRequestRegexMatcher (url_path_pattern = r"/api/cheap" , cost = 1 ),
442- HttpRequestRegexMatcher (url_path_pattern = r"/api/expensive" , cost = 10 ),
441+ HttpRequestRegexMatcher (url_path_pattern = r"/api/cheap" , weight = 1 ),
442+ HttpRequestRegexMatcher (url_path_pattern = r"/api/expensive" , weight = 10 ),
443443 ],
444444 rates = [Rate (20 , timedelta (hours = 1 ))],
445445 )
446446 budget = APIBudget (policies = [policy ])
447447
448- # Make 1 expensive request (costs 10) and 10 cheap requests (cost 1 each) = total 20
448+ # Make 1 expensive request (weight 10) and 10 cheap requests (weight 1 each) = total 20
449449 budget .acquire_call (Request ("GET" , "https://example.com/api/expensive" ), block = False )
450450 for i in range (10 ):
451451 budget .acquire_call (Request ("GET" , "https://example.com/api/cheap" ), block = False )
0 commit comments