Skip to content

Commit d2a4e6b

Browse files
committed
started to write new api
1 parent f57fd23 commit d2a4e6b

File tree

5 files changed

+176
-7
lines changed

5 files changed

+176
-7
lines changed

proxy_py/_settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
'PORT': 55555,
7979
}
8080

81+
PROXY_PROVIDER_SERVER_MAXIMUM_REQUEST_LENGTH = 1024
82+
PROXY_PROVIDER_SERVER_MAXIMUM_STRING_FIELD_SIZE = 128
83+
8184
_PROXY_PROVIDER_SERVER_API_CONFIG_FETCH_CONFIG = {
8285
'fields': [
8386
'address', 'protocol', 'auth_data', 'domain', 'port', 'last_check_time', 'number_of_bad_checks',

server/api_v2/api_request_handler.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import re
2+
3+
from proxy_py import settings
4+
from server.api_v1.requests_to_models.request_parser import ParseError
5+
from server.base_app import BaseApp
6+
7+
import aiohttp
8+
9+
10+
class ApiRequestHandler:
11+
def __init__(self, app: BaseApp):
12+
self.app = app
13+
self.methods = {
14+
'get_model': self.get_model,
15+
}
16+
17+
async def handle(self, request: aiohttp.ClientRequest, method_name: str, post_data: dict):
18+
try:
19+
response = {
20+
'status': 'ok',
21+
}
22+
if method_name not in self.methods:
23+
response = {
24+
'status': 'error',
25+
'status_code':400,
26+
'error_message': "there is no any method with this name",
27+
}
28+
else:
29+
response.update(await self.methods[method_name](post_data))
30+
except ParseError as ex:
31+
self.app.log_info(
32+
request,
33+
"Error during parsing request. Request: {} Exception: {}".format(
34+
post_data,
35+
ex
36+
)
37+
)
38+
39+
response = {
40+
'status': 'error',
41+
'status_code': 400,
42+
'error_message': str(ex)
43+
}
44+
except ValueError as ex:
45+
response = {
46+
'status': 'error',
47+
'status_code':400,
48+
'error_message': "something's wrong with your request",
49+
}
50+
self.app.log_error(
51+
request,
52+
f'ValueError: {ex}'
53+
)
54+
except BaseException as ex:
55+
response = {
56+
'status': 'error',
57+
'status_code': 500,
58+
'error_message': 'something bad happened, call the admin',
59+
}
60+
self.app.log_error(
61+
request,
62+
f'Error during execution request. Method: {method_name}. Request: {request}. Exception: {ex}'
63+
)
64+
# except ExecutionError as ex:
65+
# self.app.log_error(
66+
# request,
67+
# "Error during execution request. Request: {} Exception: {}".format(
68+
# post_data,
69+
# ex
70+
# )
71+
# )
72+
#
73+
# response = {
74+
# 'status': 'error',
75+
# 'status_code': 500,
76+
# 'error_message': 'error during execution request'
77+
# }
78+
79+
return response
80+
81+
async def get_model(self, data: dict) -> dict:
82+
if 'name' not in data:
83+
raise ParseError('please, specify the "name" key')
84+
85+
model_name = data['name']
86+
validate_letters_digits_undescores(model_name)
87+
if model_name not in settings.PROXY_PROVIDER_SERVER_API_CONFIG:
88+
raise ParseError("You're not allowed to see this model")
89+
90+
91+
return {
92+
"result": "model " + model_name,
93+
}
94+
95+
96+
def validate_letters_digits_undescores(value):
97+
if len(value) > settings.PROXY_PROVIDER_SERVER_MAXIMUM_STRING_FIELD_SIZE:
98+
raise ParseError(f'value "{value}" is too big')
99+
100+
return validate_regex(value, r'^[a-zA-Z0-9_]+$')
101+
102+
103+
def validate_regex(value: str, regex: str):
104+
if type(value) is not str:
105+
raise ParseError(f'value "{value}" should be string')
106+
107+
if not re.match(regex, value):
108+
raise ParseError(f"value \"{value}\" doesn't match to regex \"{regex}\"")

server/api_v2/app.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from proxy_py import settings
2+
from server.base_app import BaseApp
3+
from .api_request_handler import ApiRequestHandler
4+
from aiohttp import web
5+
6+
import json
7+
import aiohttp
8+
9+
10+
class App(BaseApp):
11+
def __init__(self, *args, **kwargs):
12+
super(App, self).__init__(*args, **kwargs)
13+
14+
self.request_handler = ApiRequestHandler(self)
15+
16+
async def setup_router(self):
17+
self.app.router.add_post('/{method_name:[a-z_0-9]+}', self.post)
18+
19+
async def post(self, request):
20+
method_name = request.match_info['method_name']
21+
if method_name is None or not method_name:
22+
status_code = 400
23+
response = {
24+
'status': 'error',
25+
'status_code': 400,
26+
'error_message': "bad method name",
27+
}
28+
else:
29+
data = await request.read()
30+
31+
try:
32+
data = data.decode()
33+
if len(data) > settings.PROXY_PROVIDER_SERVER_MAXIMUM_REQUEST_LENGTH:
34+
response = {
35+
'status': 'error',
36+
'status_code': 400,
37+
'error_message': "your request is too fat!",
38+
}
39+
else:
40+
data = json.loads(data)
41+
42+
response = await self.request_handler.handle(request, method_name, data)
43+
except ValueError:
44+
response = {
45+
'status': 'error',
46+
'status_code': 400,
47+
'error_message': "your request doesn't look like request",
48+
}
49+
50+
if 'status_code' in response:
51+
status_code = response['status_code']
52+
else:
53+
if response['status'] != 'ok':
54+
status_code = 500
55+
else:
56+
status_code = 200
57+
58+
response['status_code'] = status_code
59+
60+
return aiohttp.web.json_response(response, status=status_code)

server/base_app.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import asyncio
2-
31
from proxy_py import settings
42
from aiohttp import web
53

64
import abc
7-
import json
8-
import aiohttp
95
import aiohttp_jinja2
106
import jinja2
11-
import inspect
127

138

149
class BaseApp:

server/proxy_provider_server.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import json
2-
31
from proxy_py import settings
42
from .base_app import BaseApp
53
from .api_v1.app import App as ApiV1App
4+
from .api_v2.app import App as ApiV2App
65
from .frontend.app import App as FrontendApp
76
from aiohttp import web
87

8+
import json
99
import logging
1010
import aiohttp
1111
import aiohttp_jinja2
@@ -49,10 +49,13 @@ async def start(self, loop):
4949
async def setup_router(self):
5050
api_v1_app = ApiV1App(logger=self.logger)
5151
await api_v1_app.init()
52+
api_v2_app = ApiV2App(logger=self.logger)
53+
await api_v2_app.init()
5254
frontend_app = FrontendApp(logger=self.logger)
5355
await frontend_app.init()
5456

5557
self._app.add_subapp('/api/v1/', api_v1_app.app)
58+
self._app.add_subapp('/api/v2/', api_v2_app.app)
5659
self._app.add_subapp('/i/', frontend_app.app)
5760

5861
async def setup_middlewares(self):

0 commit comments

Comments
 (0)