Рабочая версия
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
*.pyc
|
||||
*.pyo
|
||||
|
||||
prototypes
|
||||
dist
|
||||
build
|
||||
25
README.md
Normal file
25
README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
```
|
||||
from router.broker import Broker
|
||||
|
||||
|
||||
broker = Broker()
|
||||
|
||||
|
||||
@broker.route(
|
||||
rule = {
|
||||
url:
|
||||
}
|
||||
)
|
||||
def foo():
|
||||
return 'foo'
|
||||
|
||||
|
||||
request = {
|
||||
url: ''
|
||||
}
|
||||
method = broker(request)
|
||||
|
||||
response = method()
|
||||
|
||||
print(response)
|
||||
```
|
||||
74
progon.py
Executable file
74
progon.py
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
|
||||
from router.broker import Broker
|
||||
from router.syntetic.url import rule_comparator
|
||||
|
||||
|
||||
broker = Broker()
|
||||
|
||||
|
||||
def comparator(rule, query):
|
||||
print('comparator')
|
||||
print(rule['url'])
|
||||
print(query['url'])
|
||||
if rule['url']['value'] == query['url']:
|
||||
return {}
|
||||
|
||||
|
||||
@broker.route(
|
||||
rule = {
|
||||
'domain': {
|
||||
'value': '',
|
||||
'isregex': True
|
||||
},
|
||||
'url': {
|
||||
'value': '',
|
||||
'isregex': True
|
||||
}
|
||||
},
|
||||
comparator = comparator
|
||||
)
|
||||
def foo():
|
||||
return 'foo'
|
||||
|
||||
|
||||
def comparator_flask(rule, query):
|
||||
print('comparator')
|
||||
print(rule['url'])
|
||||
print(query['url'])
|
||||
if rule['url'] == query['url']:
|
||||
result = rule_comparator(rule['url'], query['url'])
|
||||
print(result)
|
||||
return result
|
||||
|
||||
|
||||
@broker.route(
|
||||
rule = {
|
||||
'url': '/'
|
||||
},
|
||||
comparator = comparator_flask
|
||||
)
|
||||
def foo():
|
||||
return 'foo'
|
||||
|
||||
|
||||
request = {
|
||||
'url': '/'
|
||||
}
|
||||
broker_response = broker(request)
|
||||
print('broker_response', broker_response)
|
||||
if broker_response is not None:
|
||||
method, params = broker_response
|
||||
print('method', 'params')
|
||||
print(method, params)
|
||||
|
||||
if method is None:
|
||||
print('Маршрут не найден')
|
||||
response = None
|
||||
else:
|
||||
response = method(**params)
|
||||
|
||||
print(response)
|
||||
15
pyproject.toml
Normal file
15
pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[project]
|
||||
name = "router"
|
||||
version ="0.1.0"
|
||||
authors = [
|
||||
{ name="RemiZOffAlex", email="remizoffalex@gmail.com" },
|
||||
]
|
||||
description = "Маршрутизатор"
|
||||
requires-python = ">=3.10"
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12"
|
||||
]
|
||||
keywords = ["documentation"]
|
||||
dependencies = []
|
||||
2
router/__init__.py
Normal file
2
router/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
61
router/broker.py
Normal file
61
router/broker.py
Normal file
@@ -0,0 +1,61 @@
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
from .route import Route
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Broker:
|
||||
def __init__(self):
|
||||
self.routes = []
|
||||
|
||||
def __call__(self, query):
|
||||
"""Вызов метода
|
||||
"""
|
||||
for route in self.routes:
|
||||
print(route)
|
||||
comparator = route.comparator
|
||||
output = comparator(route.rule, query)
|
||||
if output:
|
||||
return (route.endpoint, output)
|
||||
|
||||
def __getitem__(self, key):
|
||||
method = self.methods[key]
|
||||
return method.function
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.methods)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.methods)
|
||||
|
||||
def __setitem__(self, key, function, pre=None):
|
||||
method = Method(function=function, pre=pre)
|
||||
self.methods[key] = method
|
||||
|
||||
def __delitem__(self, key):
|
||||
del self.methods[key]
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.methods)
|
||||
|
||||
def route(self, rule: dict, comparator: Callable, *args):
|
||||
"""Декоратор
|
||||
"""
|
||||
assert rule is not None, 'Не указано имя метода'
|
||||
|
||||
def wrap(function):
|
||||
_route = Route(
|
||||
rule = rule,
|
||||
comparator = comparator,
|
||||
endpoint = function
|
||||
)
|
||||
self.routes.append(_route)
|
||||
return function
|
||||
return wrap
|
||||
9
router/endpoint.py
Normal file
9
router/endpoint.py
Normal file
@@ -0,0 +1,9 @@
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
|
||||
class Endpoint:
|
||||
def __init__(self, function):
|
||||
self.function = function
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
result = self.function()
|
||||
16
router/route.py
Normal file
16
router/route.py
Normal file
@@ -0,0 +1,16 @@
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
|
||||
class Route:
|
||||
def __init__(self, rule, comparator, endpoint):
|
||||
"""
|
||||
:param rule: С чем сравнивать
|
||||
:param : Как сравнивать
|
||||
:param : Куда отправить
|
||||
"""
|
||||
self.rule = rule
|
||||
self.comparator = comparator
|
||||
self.endpoint = endpoint
|
||||
95
router/syntetic/url.py
Normal file
95
router/syntetic/url.py
Normal file
@@ -0,0 +1,95 @@
|
||||
__author__ = 'RemiZOffAlex'
|
||||
__email__ = 'remizoffalex@mail.ru'
|
||||
|
||||
import re
|
||||
|
||||
|
||||
_part_re = re.compile(
|
||||
r"""
|
||||
(?:
|
||||
(?P<slash>/) # a slash
|
||||
|
|
||||
(?P<static>[^</]+) # static rule data
|
||||
|
|
||||
(?:
|
||||
<
|
||||
(?:
|
||||
(?P<converter>[a-zA-Z_][a-zA-Z0-9_]*) # converter name
|
||||
(?:\((?P<arguments>.*?)\))? # converter arguments
|
||||
: # variable delimiter
|
||||
)?
|
||||
(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*) # variable name
|
||||
>
|
||||
)
|
||||
)
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
def rule_parse(rule: str) -> list:
|
||||
"""Парсим правило
|
||||
"""
|
||||
result = []
|
||||
pos = 0
|
||||
|
||||
while pos < len(rule):
|
||||
match = _part_re.match(rule, pos)
|
||||
print('match:', match)
|
||||
pos = match.end()
|
||||
data = match.groupdict()
|
||||
print('data:', data)
|
||||
result.append(data)
|
||||
return result
|
||||
|
||||
def rule_compile(rule: list):
|
||||
"""Компилируем регулярку из правила
|
||||
"""
|
||||
result = []
|
||||
params = {}
|
||||
for item in rule:
|
||||
if item['slash']:
|
||||
result.append(item['slash'])
|
||||
elif item['static']:
|
||||
result.append(item['static'])
|
||||
elif item['converter']:
|
||||
params[item['variable']] = None
|
||||
if item['converter']=='int':
|
||||
result.append('(?P<{}>\d+)'.format(item['variable']))
|
||||
print('item:', item)
|
||||
regexp = ''.join(result)
|
||||
print('regexp:', regexp)
|
||||
return (re.compile(regexp), params)
|
||||
|
||||
def rule_extract(regexp, request):
|
||||
pass
|
||||
|
||||
def rule_comparator(rule, request):
|
||||
try:
|
||||
rule_proto = rule_parse(rule)
|
||||
print('rule_proto:', rule_proto)
|
||||
rule_regex, params = rule_compile(rule_proto)
|
||||
print('rule:', rule_regex)
|
||||
result = rule_regex.match(url)
|
||||
for key in params:
|
||||
params[key] = result.group(key)
|
||||
print(key, ':', params[key])
|
||||
return params
|
||||
except Exception as error:
|
||||
return None
|
||||
|
||||
def main():
|
||||
print('_part_re.groups:', _part_re.groups)
|
||||
print('_part_re.groups:', _part_re.groups)
|
||||
rule = '/v<int:major>.<int:minor>'
|
||||
urls = [
|
||||
'/v3451.5432',
|
||||
'/v3sdfsdf451.5432'
|
||||
]
|
||||
|
||||
for url in urls:
|
||||
params = rule_comparator(rule, url)
|
||||
if params:
|
||||
print('route {} is valid:'.format(url), params)
|
||||
else:
|
||||
print('route {} invalid'.format(url))
|
||||
Reference in New Issue
Block a user