[Python, Программирование] Еще один фреймворк…
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Основная концепция работыВчера я зарелизил свой первый Python фреймворк. Нет, не еще один. Это в мире - еще один. А для меня пока что первый. И я допускаю, что он первый в своем роде. Это фреймворк для создания кастомных серверов. И создаваться они будут через конфиг. Ух, насоздаем сейчас...Вначале был конфигИтак, конфиг. Поскольку к этому моменту фреймворк мы уже установили. А если нет, то это легко и просто делается командой:
pip3 install idewavecore==0.0.1
Это при условии наличия у вас Python 3.6+, интернета и компьютера.Сам конфиг при этом выглядит примерно вот так:
# settings.yml
settings:
servers: !inject config_dir/servers.yml
db_connections:
sqlite:
host: ~
username: ~
password: ~
# default mysql 3306, postgresql 5432, sqlite don't need port
port: ~
# currently allowed: mysql, postgresql, sqlite
dialect: sqlite
# supported drivers:
# mysql: mysqlconnector, pymysql, pyodbc
# postgresql: psycopg2, pg8000, pygresql
driver: ~
# to use with sqlite this should be absolute db path
# can be empty to keep db in memory (sqlite only)
db_name: ~
charset: ~
Где !inject - это специальный тэг для импорта других yaml файлов. Что очень удобно, если нужно разбить огромную yaml-простыню на набор аккуратных мини-конфигов.
# servers.yml
sample_server:
connection:
host: 1.2.3.4
port: 1234
# possible values: tcp, websocket
connection_type: tcp
# optional
proxy:
host: ~
port: ~
# possible values: tcp, websocket
connection_type: tcp
options:
server_name: Sample Server
is_debug: false
middlewares: !pipe
- !fn native.test.mock_middleware
- !fn native.test.mock_middleware
- !infinite_loop
- !fn native.test.mock_middleware
- !fn native.test.mock_middleware
- !fn native.test.mock_middleware
- !router
ROUTE_1: !fn native.test.mock_middleware
ROUTE_2: !fn native.test.mock_middleware
ROUTE_3:
- !fn native.test.mock_middleware
- !fn native.test.mock_middleware
- !fn native.test.mock_middleware
# optional
db_connection: sqlite
Здесь уже побольше тэгов.!pipe - это специальный тэг, который создает обертку над функциями в массиве. На данный момент все функции, используемые в разделе middlewares (о них - чуть ниже), должны быть обернуты в пайп. Вкратце - пайп выполняет поочередно переданные в него функции и пробрасывает в них необходимые параметры.!infinite_loop - это специальный тэг, который автоматически создает пайп из переданных функций и затем выполняет их внутри вечного цикла. Что может быть полезно для создания непрерывного соединения (например, по websocket).!router - это специальный тэг, который создает маршрутизируемый пайп. Фактически, создается словарь пайпов и какой из них выполнить, роутер определяет по специальному параметру (route).И, наконец, !fn - специальный тэг, который позволяет импортировать функцию (далее - middleware) по указанному пути. Мой фреймворк предоставляет некоторое количество миддлвэров, но можно написать свои - достаточно создать в корне своего проекта одноименную папку - middlewares - и далее создать там файлы с необходимыми функциями. Далее, чтобы использовать вашу функцию, достаточно будет вызвать тэг:!fn <имя_вашего_файла>.<имя_функции> И строка будет преобразована в миддлвэр. Название корневой папки (middlewares) указывать не нужно - оно будет подставлено автоматически при импорте. Если же вы хотите использовать нативные миддлвэры фреймворка (есть! я использовал три заимствованных слова подряд!), достаточно указать префикс native в пути к функции, например:!fn native.test.mock_middlewareВ целом, большой акцент сделан именно на работу с конфигом.Middle whereМиддлвэры - это место, где будет сосредоточена вся кастомизируемая логика вашего приложения. Фактически, это - центр. Сердце каждого отдельно созданного сервера.В общих чертах, миддлвэр - это асинхронная функция, имеющая доступ ко всем хранилищам (о них - ниже). Каждая такая функция должна выглядеть примерно вот так:
from idewavecore.session import Storage, ItemFlag
async def sample_middleware(**kwargs):
global_storage: Storage = kwargs.pop('global_storage')
server_storage: Storage = kwargs.pop('server_storage')
session_storage: Storage = kwargs.pop('session_storage')
session_storage.set_items([
{
'key1': {
'value': 'some_tmp_value'
}
},
{
'key2': {
'value': 'some_persistent_value',
'flags': ItemFlag.PERSISTENT
}
},
{
'key3': {
'value': 'some_persistent_constant_value',
'flags': ItemFlag.PERSISTENT | ItemFlag.FROZEN
}
},
{
'key4': {
'value': 'some_constant_value',
'flags': ItemFlag.FROZEN
}
}
])
value_of_key3 = session_storage.get_value('key3')
Каждый миддлвэр имеет доступ к одному из трех типов хранилищ (storage). Хранилища бывают трех типов: глобальное (global storage), хранилище сервера (server storage) и хранилище сессии (session storage).Глобальное хранилище связывает все части приложения между собой, позволяя серверам получить доступ к общим данным. Хранилище сервера используется для хранения соединений и в основном используется для броадкаста.Хранилище сессий создается персонально для каждого клиентского соединения и хранит данные в пределах этого соединения.В основном в миддлвэрах будет использоваться именно хранилище сессии.(После третьего раза я понял, что больше не могу так. Простите за такой топорный перевод термина. Я не придумал, как по-другому. Предлагайте свои варианты в комментариях - возможно, эту ситуацию еще не поздно исправить.)Запускаем...Теперь наконец пора применить то, без чего не обходится ни одно нормальное приложение на базе моего фреймворка - Assembler. Не совсем тот, но тоже производит сборку. Примерно так:
# run.py
import asyncio
from idewavecore import Assembler
from idewavecore.session import Storage
if __name__ == '__main__':
loop = asyncio.get_event_loop()
global_storage = Storage()
assembler = Assembler(
global_storage=global_storage,
# ваш путь к конфигу
config_path='settings.yml'
)
servers = assembler.assemble()
for server in servers:
server.start()
loop.run_until_complete(
asyncio.gather(*[server.get() for server in servers])
)
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
loop.close()
Запускаем в терминале - и можем лицезреть (при условии, что вы все сделали правильно) сообщения о том, что серверы запущены. Теперь к ним можно пробовать достучаться всеми возможными способами - браузер, curl, клиент mmo rpg игры...Что теперьА теперь я хочу сказать спасибо всем, кто прочитал мой пост до конца. Я буду благодарен за любые конструктивные замечания. Даже если мой фреймворк - не первый в своем роде, я хочу его максимально приблизить к этой планке.Присоединяйтесь https://github.com/idewave/idewavecore.
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, Разработка под Linux, Программирование микроконтроллеров, Софт] Поскольку на Raspberry Pi Pico не встанет Linux, умелец портировал на плату Fuzix
- [Assembler, Программирование микроконтроллеров] Assembler Editor Plus: Добавление нового микроконтроллера
- Языку Python исполнилось 30 лет
- [Программирование, Java, ООП] Java Core для самых маленьких. Часть 3. Переменные
- [Разработка веб-сайтов, Программирование, IT-стандарты] Радикальный перфекционизм в коде
- [Программирование, Венчурные инвестиции, Развитие стартапа, Карьера в IT-индустрии] Пол Грэм: Над чем я работал (перевод)
- [Тестирование IT-систем, Python, Карьера в IT-индустрии, VueJS] Дайджест митапов и практикумов: Frontend, Web, QA и не только
- [Информационная безопасность, Криптография, Python, Графические оболочки, C] Поддержка токенов PKCS#11 с ГОСТ-криптографией в Python. Часть I
- [Программирование, .NET, ASP, C#] Реализуем глобальную обработку исключений в ASP.NET Core приложении (перевод)
- [Программирование, Разработка под Android, GitHub, Социальные сети и сообщества] Российский разработчик написал клиент Clubhouse для Android после реверс-инжиниринга API
Теги для поиска: #_python, #_programmirovanie (Программирование), #_python3, #_idewavecore, #_frejmvork (фреймворк), #_python, #_programmirovanie (
Программирование
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:39
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Основная концепция работыВчера я зарелизил свой первый Python фреймворк. Нет, не еще один. Это в мире - еще один. А для меня пока что первый. И я допускаю, что он первый в своем роде. Это фреймворк для создания кастомных серверов. И создаваться они будут через конфиг. Ух, насоздаем сейчас...Вначале был конфигИтак, конфиг. Поскольку к этому моменту фреймворк мы уже установили. А если нет, то это легко и просто делается командой: pip3 install idewavecore==0.0.1
# settings.yml
settings: servers: !inject config_dir/servers.yml db_connections: sqlite: host: ~ username: ~ password: ~ # default mysql 3306, postgresql 5432, sqlite don't need port port: ~ # currently allowed: mysql, postgresql, sqlite dialect: sqlite # supported drivers: # mysql: mysqlconnector, pymysql, pyodbc # postgresql: psycopg2, pg8000, pygresql driver: ~ # to use with sqlite this should be absolute db path # can be empty to keep db in memory (sqlite only) db_name: ~ charset: ~ # servers.yml
sample_server: connection: host: 1.2.3.4 port: 1234 # possible values: tcp, websocket connection_type: tcp # optional proxy: host: ~ port: ~ # possible values: tcp, websocket connection_type: tcp options: server_name: Sample Server is_debug: false middlewares: !pipe - !fn native.test.mock_middleware - !fn native.test.mock_middleware - !infinite_loop - !fn native.test.mock_middleware - !fn native.test.mock_middleware - !fn native.test.mock_middleware - !router ROUTE_1: !fn native.test.mock_middleware ROUTE_2: !fn native.test.mock_middleware ROUTE_3: - !fn native.test.mock_middleware - !fn native.test.mock_middleware - !fn native.test.mock_middleware # optional db_connection: sqlite from idewavecore.session import Storage, ItemFlag
async def sample_middleware(**kwargs): global_storage: Storage = kwargs.pop('global_storage') server_storage: Storage = kwargs.pop('server_storage') session_storage: Storage = kwargs.pop('session_storage') session_storage.set_items([ { 'key1': { 'value': 'some_tmp_value' } }, { 'key2': { 'value': 'some_persistent_value', 'flags': ItemFlag.PERSISTENT } }, { 'key3': { 'value': 'some_persistent_constant_value', 'flags': ItemFlag.PERSISTENT | ItemFlag.FROZEN } }, { 'key4': { 'value': 'some_constant_value', 'flags': ItemFlag.FROZEN } } ]) value_of_key3 = session_storage.get_value('key3') # run.py
import asyncio from idewavecore import Assembler from idewavecore.session import Storage if __name__ == '__main__': loop = asyncio.get_event_loop() global_storage = Storage() assembler = Assembler( global_storage=global_storage, # ваш путь к конфигу config_path='settings.yml' ) servers = assembler.assemble() for server in servers: server.start() loop.run_until_complete( asyncio.gather(*[server.get() for server in servers]) ) try: loop.run_forever() except KeyboardInterrupt: pass finally: loop.close() =========== Источник: habr.com =========== Похожие новости:
Программирование ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:39
Часовой пояс: UTC + 5