#!/usr/bin/env python3
"""
registry.py - Доступ к Platform Registry
ИСПОЛЬЗОВАНИЕ:
from system.core.registry import get_path, get_service, get_import
# Получить путь
workspace = get_path('workspace')
library = get_path('library')
# Получить настройки сервиса
docs_url = get_service('docs', 'url')
# Получить путь для импорта
ozon_path = get_import('ozon') # → library.connectors.api.ozon
"""
import os
import yaml
from pathlib import Path
from typing import Any, Optional
# Путь к реестру
REGISTRY_PATH = Path(__file__).parent.parent / "config" / "REGISTRY.yaml"
# Кэш реестра
_registry_cache: Optional[dict] = None
def load_registry() -> dict:
"""Загрузить реестр (с кэшированием)"""
global _registry_cache
if _registry_cache is not None:
return _registry_cache
if not REGISTRY_PATH.exists():
raise FileNotFoundError(f"Registry not found: {REGISTRY_PATH}")
with open(REGISTRY_PATH, 'r', encoding='utf-8') as f:
_registry_cache = yaml.safe_load(f)
return _registry_cache
def expand_vars(value: str) -> str:
"""Раскрыть переменные в строке ($WORKSPACE → /opt/claude-workspace)"""
if not isinstance(value, str):
return value
# Замена переменных окружения
if '$' in value:
for var in ['WORKSPACE', 'DATASPACE', 'BACKUPSPACE']:
env_value = os.getenv(var)
if env_value:
value = value.replace(f'${var}', env_value)
return value
def get_env(name: str) -> str:
"""Получить переменную окружения из реестра"""
registry = load_registry()
env = registry.get('environment', {})
value = env.get(name)
if value is None:
raise KeyError(f"Environment variable not in registry: {name}")
return expand_vars(value)
def get_path(name: str) -> str:
"""Получить путь из реестра"""
registry = load_registry()
directories = registry.get('directories', {})
path = directories.get(name)
if path is None:
raise KeyError(f"Directory not in registry: {name}")
return expand_vars(path)
def get_service(name: str, key: Optional[str] = None) -> Any:
"""Получить настройки сервиса"""
registry = load_registry()
services = registry.get('services', {})
service = services.get(name)
if service is None:
raise KeyError(f"Service not in registry: {name}")
if key is None:
return service
value = service.get(key)
if value is None:
raise KeyError(f"Service {name} has no key: {key}")
return expand_vars(value)
def get_import(name: str) -> str:
"""Получить путь для импорта из library"""
registry = load_registry()
library = registry.get('library', {})
# Поиск в connectors
connectors = library.get('connectors', {})
if name in connectors:
return connectors[name]['path']
# Поиск в functions
functions = library.get('functions', {})
if name in functions:
return functions[name]['path']
# Поиск в internal
internal = library.get('internal', {})
if name in internal:
return internal[name]['path']
# Проверить псевдонимы
aliases = registry.get('aliases', {})
if name in aliases:
return get_import(aliases[name])
raise KeyError(f"Import not in registry: {name}")
def get_project(name: str, key: Optional[str] = None) -> Any:
"""Получить информацию о проекте"""
registry = load_registry()
projects = registry.get('projects', {})
project = projects.get(name)
if project is None:
raise KeyError(f"Project not in registry: {name}")
if key is None:
return project
value = project.get(key)
if value is None:
raise KeyError(f"Project {name} has no key: {key}")
return expand_vars(value)
def resolve_alias(name: str) -> str:
"""Разрешить псевдоним"""
registry = load_registry()
aliases = registry.get('aliases', {})
return aliases.get(name, name)
def list_imports() -> dict:
"""Список всех доступных импортов"""
registry = load_registry()
library = registry.get('library', {})
result = {}
# Connectors
for name, info in library.get('connectors', {}).items():
result[name] = {
'path': info['path'],
'type': 'connector',
'description': info.get('description', ''),
}
# Functions
for name, info in library.get('functions', {}).items():
result[name] = {
'path': info['path'],
'type': 'function',
'description': info.get('description', ''),
}
# Internal
for name, info in library.get('internal', {}).items():
result[name] = {
'path': info['path'],
'type': 'internal',
'description': info.get('description', ''),
}
return result
# Для удобства
def workspace() -> str:
"""Путь к workspace"""
return get_env('WORKSPACE')
def dataspace() -> str:
"""Путь к dataspace"""
return get_env('DATASPACE')
if __name__ == '__main__':
# Демонстрация
print("=== Platform Registry ===\n")
print("Переменные окружения:")
print(f" WORKSPACE: {get_env('WORKSPACE')}")
print(f" DATASPACE: {get_env('DATASPACE')}")
print("\nПути:")
print(f" library: {get_path('library')}")
print(f" projects: {get_path('projects')}")
print("\nСервисы:")
print(f" docs: {get_service('docs', 'url')}")
print(f" file_share: {get_service('file_share', 'url')}")
print("\nИмпорты:")
print(f" ozon: {get_import('ozon')}")
print(f" onec: {get_import('onec')}")
print(f" 1c (alias): {get_import('1c')}")
print("\nВсе доступные импорты:")
for name, info in list_imports().items():
print(f" {name:20} ({info['type']:10}) → {info['path']}")