Skip to content

Commit 4be2283

Browse files
feature/Add edit/show rate limiting feature
1 parent 09d9678 commit 4be2283

8 files changed

Lines changed: 775 additions & 93 deletions

File tree

apimanager/base/context_processors.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
def api_version_processor(request):
1515
"""Returns the configured API_VERSION"""
16-
return {'API_VERSION': settings.API_VERSION['v500']}
16+
return {'API_VERSION': settings.API_VERSION['v510']}
1717

1818

1919
def portal_page(request):
@@ -82,7 +82,7 @@ def api_user_id(request):
8282
"""Returns the API user id of the logged-in user"""
8383
user_id = 'not authenticated'
8484
get_current_user_api_url = USER_CURRENT
85-
#Here we can not get the user from obp-api side, so we use the django auth user id here.
85+
#Here we can not get the user from obp-api side, so we use the django auth user id here.
8686
cache_key_django_user_id = request.session._session.get('_auth_user_id')
8787
cache_key = '{},{},{}'.format('api_user_id',get_current_user_api_url, cache_key_django_user_id)
8888
apicaches=None
@@ -112,4 +112,3 @@ def api_tester_url(request):
112112
"""Returns the URL to the API Tester for the API instance"""
113113
url = getattr(settings, 'API_TESTER_URL', None)
114114
return {'API_TESTER_URL': url}
115-

apimanager/consumers/forms.py

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,45 @@ class ApiConsumersForm(forms.Form):
1212
required=True,
1313
)
1414

15+
from_date = forms.DateTimeField(
16+
label='From Date',
17+
widget=forms.DateTimeInput(
18+
attrs={
19+
'class': 'form-control',
20+
'type': 'datetime-local',
21+
'value': '2024-01-01T00:00',
22+
}
23+
),
24+
required=False,
25+
initial='2024-01-01T00:00:00',
26+
)
27+
28+
to_date = forms.DateTimeField(
29+
label='To Date',
30+
widget=forms.DateTimeInput(
31+
attrs={
32+
'class': 'form-control',
33+
'type': 'datetime-local',
34+
'value': '2026-01-01T00:00',
35+
}
36+
),
37+
required=False,
38+
initial='2026-01-01T00:00:00',
39+
)
40+
41+
per_second_call_limit = forms.IntegerField(
42+
label='Per Second Call Limit',
43+
widget=forms.NumberInput(
44+
attrs={
45+
'class': 'form-control',
46+
}
47+
),
48+
initial=-1,
49+
required=False,
50+
)
51+
1552
per_minute_call_limit = forms.IntegerField(
16-
label='per_minute_call_limit',
53+
label='Per Minute Call Limit',
1754
widget=forms.NumberInput(
1855
attrs={
1956
'class': 'form-control',
@@ -24,7 +61,7 @@ class ApiConsumersForm(forms.Form):
2461
)
2562

2663
per_hour_call_limit = forms.IntegerField(
27-
label='per_hour_call_limit',
64+
label='Per Hour Call Limit',
2865
widget=forms.NumberInput(
2966
attrs={
3067
'class': 'form-control',
@@ -33,8 +70,9 @@ class ApiConsumersForm(forms.Form):
3370
initial=-1,
3471
required=False,
3572
)
73+
3674
per_day_call_limit = forms.IntegerField(
37-
label='per_day_call_limit',
75+
label='Per Day Call Limit',
3876
widget=forms.NumberInput(
3977
attrs={
4078
'class': 'form-control',
@@ -43,8 +81,9 @@ class ApiConsumersForm(forms.Form):
4381
initial=-1,
4482
required=False,
4583
)
84+
4685
per_week_call_limit = forms.IntegerField(
47-
label='per_week_call_limit',
86+
label='Per Week Call Limit',
4887
widget=forms.NumberInput(
4988
attrs={
5089
'class': 'form-control',
@@ -55,7 +94,7 @@ class ApiConsumersForm(forms.Form):
5594
)
5695

5796
per_month_call_limit = forms.IntegerField(
58-
label='per_month_call_limit',
97+
label='Per Month Call Limit',
5998
widget=forms.NumberInput(
6099
attrs={
61100
'class': 'form-control',
Lines changed: 170 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,184 @@
1-
.consumers #consumer-list {
2-
margin-top: 20px;
1+
.consumers #consumer-list {
2+
margin-top: 20px;
33
}
44

55
#consumers .btn-group-vertical.filter-enabled,
66
#consumers .btn-group-vertical.filter-apptype {
7-
margin-top: 10px;
7+
margin-top: 10px;
88
}
99

1010
#consumers-detail div {
11-
margin: 5px 0;
11+
margin: 5px 0;
1212
}
1313

1414
#consumers .filter a {
15-
font-size: 12px;
15+
font-size: 12px;
1616
}
1717

1818
#consumers .actions .btn {
19-
margin-bottom: 2px;
19+
margin-bottom: 2px;
20+
}
21+
22+
/* Rate Limiting Styles */
23+
#consumers-detail h2 {
24+
color: #333;
25+
border-bottom: 2px solid #007bff;
26+
padding-bottom: 10px;
27+
margin-bottom: 20px;
28+
}
29+
30+
#consumers-detail .panel-info {
31+
border-color: #bee5eb;
32+
background-color: #d1ecf1;
33+
}
34+
35+
#consumers-detail .panel-info .panel-body {
36+
background-color: #f8f9fa;
37+
border-radius: 5px;
38+
padding: 15px;
39+
}
40+
41+
#consumers-detail .text-info {
42+
color: #0c5460 !important;
43+
font-size: 16px;
44+
font-weight: bold;
45+
}
46+
47+
#consumers-detail .text-muted {
48+
color: #6c757d !important;
49+
font-size: 12px;
50+
}
51+
52+
#consumers-detail .form-group label {
53+
font-weight: bold;
54+
color: #495057;
55+
}
56+
57+
#consumers-detail .btn-primary {
58+
background-color: #007bff;
59+
border-color: #007bff;
60+
padding: 10px 20px;
61+
font-weight: bold;
62+
}
63+
64+
#consumers-detail .btn-primary:hover {
65+
background-color: #0056b3;
66+
border-color: #0056b3;
67+
}
68+
69+
/* Usage statistics 6-column layout */
70+
#consumers-detail .panel-info .col-sm-2 {
71+
min-height: 80px;
72+
padding: 10px 5px;
73+
transition: all 0.3s ease;
74+
}
75+
76+
/* Readonly fields styling */
77+
#consumers-detail input[readonly] {
78+
background-color: #f8f9fa;
79+
color: #6c757d;
80+
cursor: not-allowed;
81+
border: 1px solid #dee2e6;
82+
}
83+
84+
/* Refresh button styling */
85+
#refreshUsageBtn {
86+
transition: all 0.3s ease;
87+
margin-left: 10px;
88+
}
89+
90+
#refreshUsageBtn:hover {
91+
background-color: #138496;
92+
border-color: #117a8b;
93+
}
94+
95+
#refreshUsageBtn:disabled {
96+
opacity: 0.6;
97+
cursor: not-allowed;
98+
}
99+
100+
/* Progress bar styling */
101+
#refreshProgress {
102+
height: 10px;
103+
background-color: #f5f5f5;
104+
border-radius: 5px;
105+
overflow: hidden;
106+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
107+
}
108+
109+
#refreshProgress .progress-bar {
110+
transition: width 0.3s ease;
111+
background-color: #17a2b8;
112+
}
113+
114+
/* Usage update animation */
115+
.usage-calls {
116+
transition: background-color 0.5s ease;
117+
}
118+
119+
.usage-calls.updating {
120+
background-color: #d4edda !important;
121+
padding: 2px 6px;
122+
border-radius: 3px;
123+
}
124+
125+
/* Spinning animation for refresh icon */
126+
@keyframes spin {
127+
0% {
128+
transform: rotate(0deg);
129+
}
130+
100% {
131+
transform: rotate(360deg);
132+
}
133+
}
134+
135+
.glyphicon-spin {
136+
animation: spin 1s infinite linear;
137+
}
138+
139+
/* Panel pulse effect during refresh */
140+
.panel-refreshing {
141+
animation: pulse 2s infinite;
142+
}
143+
144+
@keyframes pulse {
145+
0% {
146+
box-shadow: 0 0 0 0 rgba(23, 162, 184, 0.7);
147+
}
148+
70% {
149+
box-shadow: 0 0 0 10px rgba(23, 162, 184, 0);
150+
}
151+
100% {
152+
box-shadow: 0 0 0 0 rgba(23, 162, 184, 0);
153+
}
154+
}
155+
156+
/* Updated data highlight */
157+
.data-updated {
158+
background-color: #d4edda;
159+
border-left: 3px solid #28a745;
160+
padding-left: 10px;
161+
transition: all 0.5s ease;
162+
}
163+
164+
/* Responsive adjustments for usage stats */
165+
@media (max-width: 768px) {
166+
#consumers-detail .panel-info .col-xs-6 {
167+
margin-bottom: 15px;
168+
}
169+
170+
#consumers-detail .panel-info .col-sm-2 {
171+
min-height: auto;
172+
}
173+
174+
#refreshUsageBtn {
175+
font-size: 12px;
176+
padding: 4px 8px;
177+
}
178+
}
179+
180+
/* Timestamp fields in configuration section */
181+
#consumers-detail .form-group input[readonly] {
182+
font-size: 12px;
183+
padding: 6px 12px;
20184
}

0 commit comments

Comments
 (0)