mcp-proxy-adapter 2.1.1__py3-none-any.whl → 2.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {mcp_proxy_adapter-2.1.1.dist-info → mcp_proxy_adapter-2.1.3.dist-info}/METADATA +1 -1
  2. mcp_proxy_adapter-2.1.3.dist-info/RECORD +18 -0
  3. mcp_proxy_adapter-2.1.3.dist-info/top_level.txt +1 -0
  4. docs/README.md +0 -172
  5. docs/README_ru.md +0 -172
  6. docs/architecture.md +0 -251
  7. docs/architecture_ru.md +0 -343
  8. docs/command_development.md +0 -250
  9. docs/command_development_ru.md +0 -593
  10. docs/deployment.md +0 -251
  11. docs/deployment_ru.md +0 -1298
  12. docs/examples.md +0 -254
  13. docs/examples_ru.md +0 -401
  14. docs/mcp_proxy_adapter.md +0 -251
  15. docs/mcp_proxy_adapter_ru.md +0 -405
  16. docs/quickstart.md +0 -251
  17. docs/quickstart_ru.md +0 -397
  18. docs/testing.md +0 -255
  19. docs/testing_ru.md +0 -469
  20. docs/validation_ru.md +0 -287
  21. examples/analyze_config.py +0 -141
  22. examples/basic_integration.py +0 -161
  23. examples/docstring_and_schema_example.py +0 -60
  24. examples/extension_example.py +0 -60
  25. examples/help_best_practices.py +0 -67
  26. examples/help_usage.py +0 -64
  27. examples/mcp_proxy_client.py +0 -131
  28. examples/mcp_proxy_config.json +0 -175
  29. examples/openapi_server.py +0 -369
  30. examples/project_structure_example.py +0 -47
  31. examples/testing_example.py +0 -53
  32. mcp_proxy_adapter-2.1.1.dist-info/RECORD +0 -61
  33. mcp_proxy_adapter-2.1.1.dist-info/top_level.txt +0 -5
  34. scripts/code_analyzer/code_analyzer.py +0 -328
  35. scripts/code_analyzer/register_commands.py +0 -446
  36. scripts/publish.py +0 -85
  37. tests/conftest.py +0 -12
  38. tests/test_adapter.py +0 -529
  39. tests/test_adapter_coverage.py +0 -274
  40. tests/test_basic_dispatcher.py +0 -169
  41. tests/test_command_registry.py +0 -328
  42. tests/test_examples.py +0 -32
  43. tests/test_mcp_proxy_adapter.py +0 -568
  44. tests/test_mcp_proxy_adapter_basic.py +0 -262
  45. tests/test_part1.py +0 -348
  46. tests/test_part2.py +0 -524
  47. tests/test_schema.py +0 -358
  48. tests/test_simple_adapter.py +0 -251
  49. {mcp_proxy_adapter-2.1.1.dist-info → mcp_proxy_adapter-2.1.3.dist-info}/WHEEL +0 -0
  50. {mcp_proxy_adapter-2.1.1.dist-info → mcp_proxy_adapter-2.1.3.dist-info}/licenses/LICENSE +0 -0
docs/deployment_ru.md DELETED
@@ -1,1298 +0,0 @@
1
- # Руководство по развертыванию Command Registry
2
-
3
- В этом руководстве описаны подходы и рекомендации по развертыванию приложений, использующих Command Registry, в различных окружениях.
4
-
5
- ## Содержание
6
-
7
- - [Подготовка к развертыванию](#подготовка-к-развертыванию)
8
- - [Развертывание в Docker](#развертывание-в-docker)
9
- - [Развертывание на VPS](#развертывание-на-vps)
10
- - [Развертывание в Kubernetes](#развертывание-в-kubernetes)
11
- - [CI/CD для Command Registry](#cicd-для-command-registry)
12
- - [Мониторинг и логирование](#мониторинг-и-логирование)
13
- - [Масштабирование](#масштабирование)
14
- - [Безопасность](#безопасность)
15
- - [Гибридная схема и интеграция с MCPProxy](#гибридная-схема-и-интеграция-с-mcpproxy)
16
-
17
- ## Подготовка к развертыванию
18
-
19
- ### 1. Создание пакета приложения
20
-
21
- Для удобного развертывания рекомендуется оформить приложение как Python-пакет:
22
-
23
- ```
24
- my_app/
25
- ├── pyproject.toml
26
- ├── setup.py
27
- ├── setup.cfg
28
- ├── README.md
29
- ├── src/
30
- │ └── my_app/
31
- │ ├── __init__.py
32
- │ ├── commands/
33
- │ │ ├── __init__.py
34
- │ │ └── ...
35
- │ ├── app.py
36
- │ └── main.py
37
- └── tests/
38
- └── ...
39
- ```
40
-
41
- Пример `pyproject.toml`:
42
-
43
- ```toml
44
- [build-system]
45
- requires = ["setuptools>=42", "wheel"]
46
- build-backend = "setuptools.build_meta"
47
-
48
- [project]
49
- name = "my-app"
50
- version = "0.1.0"
51
- description = "Command Registry Application"
52
- authors = [{name = "Your Name", email = "your.email@example.com"}]
53
- requires-python = ">=3.8"
54
- dependencies = [
55
- "command-registry>=0.1.0",
56
- "fastapi>=0.68.0",
57
- "uvicorn>=0.15.0",
58
- ]
59
- ```
60
-
61
- ### 2. Настройка конфигурации
62
-
63
- Создайте систему конфигурации, поддерживающую различные окружения:
64
-
65
- ```python
66
- # src/my_app/config.py
67
- import os
68
- from pydantic import BaseSettings
69
-
70
- class Settings(BaseSettings):
71
- """Настройки приложения."""
72
- APP_NAME: str = "Command Registry App"
73
- DEBUG: bool = False
74
- LOG_LEVEL: str = "INFO"
75
- API_PORT: int = 8000
76
-
77
- # Настройки Command Registry
78
- STRICT_MODE: bool = True
79
- AUTO_FIX: bool = False
80
-
81
- # Настройки базы данных
82
- DB_HOST: str = "localhost"
83
- DB_PORT: int = 5432
84
- DB_USER: str = "postgres"
85
- DB_PASSWORD: str = ""
86
- DB_NAME: str = "app_db"
87
-
88
- class Config:
89
- env_file = ".env"
90
- env_prefix = "APP_"
91
-
92
- # Загрузка настроек
93
- settings = Settings()
94
- ```
95
-
96
- ### 3. Создание точки входа
97
-
98
- ```python
99
- # src/my_app/main.py
100
- import uvicorn
101
- from my_app.app import app
102
- from my_app.config import settings
103
-
104
- def start():
105
- """Запускает приложение."""
106
- uvicorn.run(
107
- "my_app.app:app",
108
- host="0.0.0.0",
109
- port=settings.API_PORT,
110
- log_level=settings.LOG_LEVEL.lower(),
111
- reload=settings.DEBUG
112
- )
113
-
114
- if __name__ == "__main__":
115
- start()
116
- ```
117
-
118
- ## Развертывание в Docker
119
-
120
- ### 1. Создание Dockerfile
121
-
122
- ```dockerfile
123
- FROM python:3.10-slim
124
-
125
- WORKDIR /app
126
-
127
- # Копирование файлов зависимостей
128
- COPY pyproject.toml setup.py setup.cfg ./
129
-
130
- # Установка зависимостей
131
- RUN pip install --no-cache-dir .
132
-
133
- # Копирование кода приложения
134
- COPY src/ ./src/
135
-
136
- # Определение переменных окружения
137
- ENV APP_DEBUG=false \
138
- APP_LOG_LEVEL=INFO \
139
- APP_API_PORT=8000 \
140
- APP_STRICT_MODE=true \
141
- APP_AUTO_FIX=false
142
-
143
- # Открываем порт
144
- EXPOSE 8000
145
-
146
- # Запуск приложения
147
- CMD ["python", "-m", "my_app.main"]
148
- ```
149
-
150
- ### 2. Docker Compose для локальной разработки
151
-
152
- ```yaml
153
- # docker-compose.yml
154
- version: '3.8'
155
-
156
- services:
157
- app:
158
- build: .
159
- ports:
160
- - "8000:8000"
161
- environment:
162
- - APP_DEBUG=true
163
- - APP_LOG_LEVEL=DEBUG
164
- - APP_DB_HOST=db
165
- depends_on:
166
- - db
167
- volumes:
168
- - ./src:/app/src
169
-
170
- db:
171
- image: postgres:14
172
- environment:
173
- - POSTGRES_USER=postgres
174
- - POSTGRES_PASSWORD=postgres
175
- - POSTGRES_DB=app_db
176
- volumes:
177
- - postgres_data:/var/lib/postgresql/data
178
- ports:
179
- - "5432:5432"
180
-
181
- volumes:
182
- postgres_data:
183
- ```
184
-
185
- ### 3. Сборка и запуск
186
-
187
- ```bash
188
- # Сборка образа
189
- docker build -t my-app .
190
-
191
- # Запуск контейнера
192
- docker run -p 8000:8000 my-app
193
-
194
- # Или с использованием Docker Compose
195
- docker-compose up
196
- ```
197
-
198
- ## Развертывание на VPS
199
-
200
- ### 1. Установка зависимостей на сервере
201
-
202
- ```bash
203
- # Обновление пакетов
204
- sudo apt update
205
- sudo apt upgrade -y
206
-
207
- # Установка Python и зависимостей
208
- sudo apt install -y python3 python3-pip python3-venv
209
-
210
- # Установка Nginx
211
- sudo apt install -y nginx
212
-
213
- # Установка Supervisor
214
- sudo apt install -y supervisor
215
- ```
216
-
217
- ### 2. Настройка Gunicorn
218
-
219
- ```bash
220
- # Создание виртуального окружения
221
- python3 -m venv venv
222
- source venv/bin/activate
223
-
224
- # Установка приложения и Gunicorn
225
- pip install gunicorn
226
- pip install . # установка вашего приложения
227
- ```
228
-
229
- ### 3. Настройка Supervisor
230
-
231
- ```ini
232
- # /etc/supervisor/conf.d/my-app.conf
233
- [program:my-app]
234
- command=/home/user/my-app/venv/bin/gunicorn -w 4 -k uvicorn.workers.UvicornWorker my_app.app:app -b 127.0.0.1:8000
235
- directory=/home/user/my-app
236
- user=user
237
- autostart=true
238
- autorestart=true
239
- environment=APP_DEBUG=false,APP_LOG_LEVEL=INFO,APP_STRICT_MODE=true
240
-
241
- [supervisord]
242
- logfile=/var/log/supervisor/supervisord.log
243
- ```
244
-
245
- ### 4. Настройка Nginx
246
-
247
- ```nginx
248
- # /etc/nginx/sites-available/my-app
249
- server {
250
- listen 80;
251
- server_name example.com;
252
-
253
- location / {
254
- proxy_pass http://127.0.0.1:8000;
255
- proxy_set_header Host $host;
256
- proxy_set_header X-Real-IP $remote_addr;
257
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
258
- proxy_set_header X-Forwarded-Proto $scheme;
259
- }
260
- }
261
- ```
262
-
263
- ### 5. Активация конфигурации
264
-
265
- ```bash
266
- # Активация конфигурации Nginx
267
- sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
268
- sudo nginx -t
269
- sudo systemctl restart nginx
270
-
271
- # Запуск приложения через Supervisor
272
- sudo supervisorctl reread
273
- sudo supervisorctl update
274
- sudo supervisorctl start my-app
275
- ```
276
-
277
- ## Развертывание в Kubernetes
278
-
279
- ### 1. Создание Kubernetes Deployment
280
-
281
- ```yaml
282
- # k8s/deployment.yaml
283
- apiVersion: apps/v1
284
- kind: Deployment
285
- metadata:
286
- name: my-app
287
- labels:
288
- app: my-app
289
- spec:
290
- replicas: 3
291
- selector:
292
- matchLabels:
293
- app: my-app
294
- template:
295
- metadata:
296
- labels:
297
- app: my-app
298
- spec:
299
- containers:
300
- - name: my-app
301
- image: my-app:latest
302
- imagePullPolicy: Always
303
- ports:
304
- - containerPort: 8000
305
- env:
306
- - name: APP_DEBUG
307
- value: "false"
308
- - name: APP_LOG_LEVEL
309
- value: "INFO"
310
- - name: APP_DB_HOST
311
- value: "postgres-service"
312
- resources:
313
- limits:
314
- cpu: "500m"
315
- memory: "512Mi"
316
- requests:
317
- cpu: "100m"
318
- memory: "256Mi"
319
- readinessProbe:
320
- httpGet:
321
- path: /health
322
- port: 8000
323
- initialDelaySeconds: 5
324
- periodSeconds: 10
325
- livenessProbe:
326
- httpGet:
327
- path: /health
328
- port: 8000
329
- initialDelaySeconds: 15
330
- periodSeconds: 20
331
- ```
332
-
333
- ### 2. Создание Service
334
-
335
- ```yaml
336
- # k8s/service.yaml
337
- apiVersion: v1
338
- kind: Service
339
- metadata:
340
- name: my-app-service
341
- spec:
342
- selector:
343
- app: my-app
344
- ports:
345
- - port: 80
346
- targetPort: 8000
347
- type: ClusterIP
348
- ```
349
-
350
- ### 3. Создание Ingress
351
-
352
- ```yaml
353
- # k8s/ingress.yaml
354
- apiVersion: networking.k8s.io/v1
355
- kind: Ingress
356
- metadata:
357
- name: my-app-ingress
358
- annotations:
359
- nginx.ingress.kubernetes.io/rewrite-target: /
360
- spec:
361
- rules:
362
- - host: api.example.com
363
- http:
364
- paths:
365
- - path: /
366
- pathType: Prefix
367
- backend:
368
- service:
369
- name: my-app-service
370
- port:
371
- number: 80
372
- tls:
373
- - hosts:
374
- - api.example.com
375
- secretName: api-tls-secret
376
- ```
377
-
378
- ### 4. Развертывание в Kubernetes
379
-
380
- ```bash
381
- # Применение манифестов
382
- kubectl apply -f k8s/deployment.yaml
383
- kubectl apply -f k8s/service.yaml
384
- kubectl apply -f k8s/ingress.yaml
385
-
386
- # Проверка состояния
387
- kubectl get pods
388
- kubectl get services
389
- kubectl get ingress
390
- ```
391
-
392
- ## CI/CD для Command Registry
393
-
394
- ### 1. GitHub Actions
395
-
396
- ```yaml
397
- # .github/workflows/ci.yml
398
- name: CI/CD Pipeline
399
-
400
- on:
401
- push:
402
- branches: [ main ]
403
- pull_request:
404
- branches: [ main ]
405
-
406
- jobs:
407
- test:
408
- runs-on: ubuntu-latest
409
- steps:
410
- - uses: actions/checkout@v2
411
- - name: Set up Python
412
- uses: actions/setup-python@v2
413
- with:
414
- python-version: '3.10'
415
- - name: Install dependencies
416
- run: |
417
- python -m pip install --upgrade pip
418
- pip install pytest pytest-cov
419
- pip install -e .
420
- - name: Run tests
421
- run: |
422
- pytest --cov=my_app
423
-
424
- validate-commands:
425
- runs-on: ubuntu-latest
426
- steps:
427
- - uses: actions/checkout@v2
428
- - name: Set up Python
429
- uses: actions/setup-python@v2
430
- with:
431
- python-version: '3.10'
432
- - name: Install dependencies
433
- run: |
434
- python -m pip install --upgrade pip
435
- pip install -e .
436
- - name: Validate commands
437
- run: |
438
- python -m my_app.tools.validate_commands --strict
439
-
440
- build-and-push:
441
- needs: [test, validate-commands]
442
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
443
- runs-on: ubuntu-latest
444
- steps:
445
- - uses: actions/checkout@v2
446
- - name: Build and push Docker image
447
- uses: docker/build-push-action@v2
448
- with:
449
- context: .
450
- push: true
451
- tags: ghcr.io/${{ github.repository }}:latest
452
- ```
453
-
454
- ### 2. Скрипт для валидации команд
455
-
456
- ```python
457
- # src/my_app/tools/validate_commands.py
458
- import argparse
459
- import sys
460
- from my_app.app import registry
461
-
462
- def validate_commands(strict: bool = True) -> bool:
463
- """
464
- Проверяет все команды на соответствие требованиям документации.
465
-
466
- Args:
467
- strict: Если True, возвращает ошибку при несоответствии
468
-
469
- Returns:
470
- bool: True если все команды валидны, False иначе
471
- """
472
- result = registry.validate_all_commands(strict=strict)
473
-
474
- print(f"Проверено команд: {result['total']}")
475
- print(f"Успешно: {result['successful']}")
476
- print(f"С ошибками: {result['failed']}")
477
-
478
- if result['failed'] > 0:
479
- print("\nКоманды с ошибками:")
480
- for command, errors in result['errors'].items():
481
- print(f"\n{command}:")
482
- for error in errors:
483
- print(f" - {error}")
484
-
485
- return result['failed'] == 0
486
-
487
- if __name__ == "__main__":
488
- parser = argparse.ArgumentParser(description="Валидация команд")
489
- parser.add_argument("--strict", action="store_true", help="Строгий режим проверки")
490
- args = parser.parse_args()
491
-
492
- success = validate_commands(strict=args.strict)
493
- sys.exit(0 if success else 1)
494
- ```
495
-
496
- ## Мониторинг и логирование
497
-
498
- ### 1. Настройка логирования
499
-
500
- ```python
501
- # src/my_app/logging.py
502
- import logging
503
- import sys
504
- from logging.handlers import RotatingFileHandler
505
- from my_app.config import settings
506
-
507
- def setup_logging():
508
- """Настраивает логирование для приложения."""
509
- log_level = getattr(logging, settings.LOG_LEVEL.upper())
510
-
511
- # Настройка корневого логгера
512
- root_logger = logging.getLogger()
513
- root_logger.setLevel(log_level)
514
-
515
- # Форматтер для логов
516
- formatter = logging.Formatter(
517
- '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
518
- )
519
-
520
- # Обработчик для вывода в консоль
521
- console_handler = logging.StreamHandler(sys.stdout)
522
- console_handler.setFormatter(formatter)
523
- root_logger.addHandler(console_handler)
524
-
525
- # Обработчик для записи в файл (в production)
526
- if not settings.DEBUG:
527
- file_handler = RotatingFileHandler(
528
- 'app.log',
529
- maxBytes=10485760, # 10 MB
530
- backupCount=5
531
- )
532
- file_handler.setFormatter(formatter)
533
- root_logger.addHandler(file_handler)
534
-
535
- # Отключаем логи библиотек
536
- for logger_name in ['uvicorn.access']:
537
- logging.getLogger(logger_name).setLevel(logging.WARNING)
538
- ```
539
-
540
- ### 2. Prometheus метрики
541
-
542
- ```python
543
- # src/my_app/monitoring.py
544
- from prometheus_client import Counter, Histogram, Summary
545
- import time
546
-
547
- # Счетчики для команд
548
- command_counter = Counter(
549
- 'command_calls_total',
550
- 'Total number of command calls',
551
- ['command', 'status']
552
- )
553
-
554
- # Гистограмма времени выполнения
555
- command_duration = Histogram(
556
- 'command_duration_seconds',
557
- 'Command execution duration in seconds',
558
- ['command']
559
- )
560
-
561
- # Middleware для измерения времени выполнения команд
562
- class CommandMetricsMiddleware:
563
- def __init__(self, dispatcher):
564
- self.dispatcher = dispatcher
565
- self.original_execute = dispatcher.execute
566
- dispatcher.execute = self.execute_with_metrics
567
-
568
- def execute_with_metrics(self, command_name, **params):
569
- start_time = time.time()
570
- try:
571
- result = self.original_execute(command_name, **params)
572
- command_counter.labels(command=command_name, status="success").inc()
573
- return result
574
- except Exception as e:
575
- command_counter.labels(command=command_name, status="error").inc()
576
- raise
577
- finally:
578
- duration = time.time() - start_time
579
- command_duration.labels(command=command_name).observe(duration)
580
- ```
581
-
582
- ### 3. Интеграция с FastAPI
583
-
584
- ```python
585
- # src/my_app/app.py
586
- from fastapi import FastAPI, Request
587
- from fastapi.middleware.cors import CORSMiddleware
588
- from fastapi.responses import JSONResponse
589
- import time
590
- from starlette.middleware.base import BaseHTTPMiddleware
591
- from prometheus_client import make_asgi_app
592
-
593
- from my_app.config import settings
594
- from my_app.logging import setup_logging
595
- from my_app.registry import create_registry
596
- from my_app.monitoring import CommandMetricsMiddleware
597
-
598
- # Настройка логирования
599
- setup_logging()
600
-
601
- # Создание приложения
602
- app = FastAPI(
603
- title=settings.APP_NAME,
604
- debug=settings.DEBUG
605
- )
606
-
607
- # Добавление middleware для CORS
608
- app.add_middleware(
609
- CORSMiddleware,
610
- allow_origins=["*"],
611
- allow_credentials=True,
612
- allow_methods=["*"],
613
- allow_headers=["*"],
614
- )
615
-
616
- # Middleware для измерения времени запросов
617
- class RequestTimingMiddleware(BaseHTTPMiddleware):
618
- async def dispatch(self, request: Request, call_next):
619
- start_time = time.time()
620
- response = await call_next(request)
621
- process_time = time.time() - start_time
622
- response.headers["X-Process-Time"] = str(process_time)
623
- return response
624
-
625
- app.add_middleware(RequestTimingMiddleware)
626
-
627
- # Создание и настройка реестра команд
628
- registry = create_registry(
629
- strict=settings.STRICT_MODE,
630
- auto_fix=settings.AUTO_FIX
631
- )
632
-
633
- # Применение метрик к диспетчеру команд
634
- CommandMetricsMiddleware(registry.dispatcher)
635
-
636
- # Добавление Prometheus метрик
637
- metrics_app = make_asgi_app()
638
- app.mount("/metrics", metrics_app)
639
-
640
- # Эндпоинт для проверки состояния
641
- @app.get("/health")
642
- async def health_check():
643
- return {"status": "ok"}
644
-
645
- # Регистрация адаптера REST API
646
- from command_registry.adapters import RESTAdapter
647
- rest_adapter = RESTAdapter(registry)
648
- rest_adapter.register_endpoints(app)
649
- ```
650
-
651
- ## Масштабирование
652
-
653
- ### 1. Горизонтальное масштабирование
654
-
655
- Приложения с Command Registry могут легко масштабироваться горизонтально, так как не имеют состояния. Для масштабирования:
656
-
657
- - Используйте балансировщик нагрузки (Nginx, HAProxy)
658
- - В Kubernetes увеличьте количество реплик
659
- - Используйте автомасштабирование на основе метрик
660
-
661
- ```yaml
662
- # k8s/hpa.yaml
663
- apiVersion: autoscaling/v2
664
- kind: HorizontalPodAutoscaler
665
- metadata:
666
- name: my-app-hpa
667
- spec:
668
- scaleTargetRef:
669
- apiVersion: apps/v1
670
- kind: Deployment
671
- name: my-app
672
- minReplicas: 2
673
- maxReplicas: 10
674
- metrics:
675
- - type: Resource
676
- resource:
677
- name: cpu
678
- target:
679
- type: Utilization
680
- averageUtilization: 70
681
- ```
682
-
683
- ### 2. Асинхронное выполнение команд
684
-
685
- Для долго выполняющихся команд используйте асинхронное выполнение:
686
-
687
- ```python
688
- # src/my_app/commands/async_commands.py
689
- import asyncio
690
- from typing import Dict, Any, List
691
- import logging
692
-
693
- logger = logging.getLogger(__name__)
694
-
695
- async def process_large_dataset(data_id: str, options: Dict[str, Any] = None) -> Dict[str, Any]:
696
- """
697
- Асинхронно обрабатывает большой набор данных.
698
-
699
- Args:
700
- data_id: Идентификатор набора данных
701
- options: Опции обработки
702
-
703
- Returns:
704
- Dict[str, Any]: Результат обработки
705
- """
706
- logger.info(f"Starting processing of dataset {data_id}")
707
-
708
- # Имитация долгой обработки
709
- await asyncio.sleep(5)
710
-
711
- logger.info(f"Completed processing of dataset {data_id}")
712
- return {
713
- "data_id": data_id,
714
- "status": "completed",
715
- "results": [
716
- {"item_id": 1, "value": 100},
717
- {"item_id": 2, "value": 200}
718
- ]
719
- }
720
- ```
721
-
722
- ### 3. Очереди задач с Celery
723
-
724
- ```python
725
- # src/my_app/tasks.py
726
- from celery import Celery
727
- from my_app.config import settings
728
-
729
- # Создание Celery приложения
730
- celery_app = Celery(
731
- 'my_app',
732
- broker=f'redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}/0',
733
- backend=f'redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}/0',
734
- )
735
-
736
- # Настройка Celery
737
- celery_app.conf.update(
738
- worker_concurrency=4,
739
- task_serializer='json',
740
- accept_content=['json'],
741
- result_serializer='json',
742
- timezone='UTC',
743
- enable_utc=True,
744
- )
745
-
746
- @celery_app.task(name="process_data")
747
- def process_data_task(data_id, options=None):
748
- """Фоновая задача для обработки данных."""
749
- from my_app.commands.data_commands import process_data
750
- return process_data(data_id, options)
751
- ```
752
-
753
- ### 4. Интеграция с Command Registry
754
-
755
- ```python
756
- # src/my_app/commands/background_commands.py
757
- from typing import Dict, Any
758
- from my_app.tasks import process_data_task
759
-
760
- def start_data_processing(data_id: str, options: Dict[str, Any] = None) -> Dict[str, Any]:
761
- """
762
- Запускает обработку данных в фоновом режиме.
763
-
764
- Args:
765
- data_id: Идентификатор набора данных
766
- options: Опции обработки
767
-
768
- Returns:
769
- Dict[str, Any]: Информация о запущенной задаче
770
- """
771
- # Запуск задачи в Celery
772
- task = process_data_task.delay(data_id, options)
773
-
774
- return {
775
- "task_id": task.id,
776
- "status": "started",
777
- "data_id": data_id
778
- }
779
-
780
- def get_task_status(task_id: str) -> Dict[str, Any]:
781
- """
782
- Получает статус фоновой задачи.
783
-
784
- Args:
785
- task_id: Идентификатор задачи
786
-
787
- Returns:
788
- Dict[str, Any]: Статус и результат задачи, если она завершена
789
- """
790
- from my_app.tasks import celery_app
791
- task = celery_app.AsyncResult(task_id)
792
-
793
- result = {
794
- "task_id": task_id,
795
- "status": task.status,
796
- }
797
-
798
- if task.status == 'SUCCESS':
799
- result["result"] = task.result
800
- elif task.status == 'FAILURE':
801
- result["error"] = str(task.result)
802
-
803
- return result
804
- ```
805
-
806
- ## Безопасность
807
-
808
- ### 1. Аутентификация и авторизация
809
-
810
- ```python
811
- # src/my_app/auth.py
812
- from fastapi import Depends, HTTPException, status
813
- from fastapi.security import OAuth2PasswordBearer
814
- import jwt
815
- from datetime import datetime, timedelta
816
- from typing import Dict, Any, Optional
817
- from my_app.config import settings
818
-
819
- # Схема OAuth2
820
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
821
-
822
- def create_token(data: Dict[str, Any], expires_delta: timedelta = None) -> str:
823
- """Создает JWT токен."""
824
- to_encode = data.copy()
825
-
826
- if expires_delta:
827
- expire = datetime.utcnow() + expires_delta
828
- else:
829
- expire = datetime.utcnow() + timedelta(minutes=15)
830
-
831
- to_encode.update({"exp": expire})
832
- encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm="HS256")
833
- return encoded_jwt
834
-
835
- async def get_current_user(token: str = Depends(oauth2_scheme)) -> Dict[str, Any]:
836
- """Получает текущего пользователя по токену."""
837
- credentials_exception = HTTPException(
838
- status_code=status.HTTP_401_UNAUTHORIZED,
839
- detail="Could not validate credentials",
840
- headers={"WWW-Authenticate": "Bearer"},
841
- )
842
-
843
- try:
844
- payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
845
- username: str = payload.get("sub")
846
- if username is None:
847
- raise credentials_exception
848
- except jwt.PyJWTError:
849
- raise credentials_exception
850
-
851
- # Здесь должен быть код для получения пользователя из базы данных
852
- user = {"username": username, "role": payload.get("role", "user")}
853
- return user
854
-
855
- def check_permission(user: Dict[str, Any], required_role: str) -> bool:
856
- """Проверяет, имеет ли пользователь требуемую роль."""
857
- return user.get("role") == required_role
858
- ```
859
-
860
- ### 2. Защита эндпоинтов
861
-
862
- ```python
863
- # src/my_app/app.py
864
- from fastapi import Depends, HTTPException, status
865
- from my_app.auth import get_current_user, check_permission
866
-
867
- # Защита эндпоинта требованием аутентификации
868
- @app.post("/protected/command/{command_name}")
869
- async def execute_protected_command(
870
- command_name: str,
871
- params: Dict[str, Any],
872
- current_user: Dict[str, Any] = Depends(get_current_user)
873
- ):
874
- """Защищенный эндпоинт для выполнения команд."""
875
- # Проверка разрешений
876
- if not check_permission(current_user, "admin") and command_name.startswith("admin_"):
877
- raise HTTPException(
878
- status_code=status.HTTP_403_FORBIDDEN,
879
- detail="Not enough permissions"
880
- )
881
-
882
- # Выполнение команды
883
- try:
884
- result = registry.dispatcher.execute(command_name, **params)
885
- return {"result": result}
886
- except Exception as e:
887
- raise HTTPException(
888
- status_code=status.HTTP_400_BAD_REQUEST,
889
- detail=str(e)
890
- )
891
- ```
892
-
893
- ### 3. Защита от распространенных уязвимостей
894
-
895
- ```python
896
- # src/my_app/app.py
897
- from fastapi import FastAPI
898
- from fastapi.middleware.trustedhost import TrustedHostMiddleware
899
- from fastapi.middleware.gzip import GZipMiddleware
900
- from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
901
-
902
- app = FastAPI()
903
-
904
- # Редирект на HTTPS
905
- if not settings.DEBUG:
906
- app.add_middleware(HTTPSRedirectMiddleware)
907
-
908
- # Ограничение хостов
909
- app.add_middleware(
910
- TrustedHostMiddleware,
911
- allowed_hosts=["api.example.com", "localhost"]
912
- )
913
-
914
- # Сжатие ответов
915
- app.add_middleware(GZipMiddleware, minimum_size=1000)
916
-
917
- # Настройка заголовков безопасности
918
- @app.middleware("http")
919
- async def add_security_headers(request, call_next):
920
- response = await call_next(request)
921
- response.headers["X-Content-Type-Options"] = "nosniff"
922
- response.headers["X-Frame-Options"] = "DENY"
923
- response.headers["Content-Security-Policy"] = "default-src 'self'"
924
- response.headers["X-XSS-Protection"] = "1; mode=block"
925
- return response
926
- ```
927
-
928
- ## Заключение
929
-
930
- При развертывании приложений с Command Registry важно учитывать:
931
-
932
- 1. **Конфигурацию** - используйте переменные окружения и файлы .env
933
- 2. **Логирование** - настройте логирование для отладки и мониторинга
934
- 3. **Масштабирование** - разработайте приложение для горизонтального масштабирования
935
- 4. **Безопасность** - защитите API с помощью аутентификации и авторизации
936
- 5. **CI/CD** - автоматизируйте тестирование и развертывание
937
- 6. **Мониторинг** - отслеживайте метрики производительности и использования
938
-
939
- Эти рекомендации помогут вам успешно развернуть и поддерживать приложения на основе Command Registry в различных окружениях.
940
-
941
- ## Гибридная схема и интеграция с MCPProxy
942
-
943
- ### Проблема масштабирования OpenAPI схем
944
-
945
- При большом количестве команд документация OpenAPI становится громоздкой и трудной для обработки. Это создает следующие проблемы:
946
-
947
- 1. Модели ИИ могут не справляться с обработкой больших схем
948
- 2. Клиентские библиотеки генерируются с ошибками
949
- 3. Документация становится менее удобной для разработчиков
950
- 4. Увеличивается время загрузки Swagger UI
951
-
952
- ### Решение: гибридная архитектура REST+JSONRPC
953
-
954
- Command Registry предлагает гибридный подход, сочетающий преимущества REST и JSONRPC:
955
-
956
- ```
957
- ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐
958
- │ │ │ │ │ │
959
- │ Command Registry │───►│ Гибридная схема │───►│ REST + JSONRPC API│
960
- │ │ │ │ │ │
961
- └───────────────────┘ └───────────────────┘ └───────────────────┘
962
-
963
-
964
- ┌───────────────────┐
965
- │ │
966
- │ MCPProxy │
967
- │ │
968
- └───────────────────┘
969
-
970
-
971
- ┌───────────────────┐
972
- │ │
973
- │ Инструменты модели│
974
- │ │
975
- └───────────────────┘
976
- ```
977
-
978
- #### Компоненты решения:
979
-
980
- 1. **Традиционные REST эндпоинты** для стандартных операций
981
- 2. **Универсальный эндпоинт `cmd`** принимающий JSONRPC запросы
982
- 3. **Генератор гибридной схемы** создающий оптимизированную документацию API
983
-
984
- ### Генератор гибридной схемы
985
-
986
- Для генерации гибридной схемы был создан отдельный генератор, который:
987
-
988
- 1. Анализирует команды из Command Registry
989
- 2. Создает оптимизированную OpenAPI схему
990
- 3. Формирует универсальный эндпоинт для JSONRPC
991
- 4. Поддерживает обратную совместимость с существующими клиентами
992
-
993
- ```python
994
- # Пример использования генератора гибридной схемы
995
- from command_registry.generators.hybrid_generator import HybridAPIGenerator
996
- from my_app.registry import registry
997
-
998
- # Создаем генератор
999
- generator = HybridAPIGenerator(
1000
- title="My Hybrid API",
1001
- description="API с поддержкой REST и JSONRPC",
1002
- version="1.0.0",
1003
- cmd_endpoint="/api/cmd"
1004
- )
1005
-
1006
- # Регистрируем в Command Registry
1007
- registry.add_generator(generator)
1008
-
1009
- # Применяем к FastAPI приложению
1010
- app = FastAPI()
1011
- generator.apply_to_fastapi(app)
1012
- ```
1013
-
1014
- ### Интеграция с MCPProxy
1015
-
1016
- MCPProxy позволяет преобразовать OpenAPI серверы в инструменты для моделей ИИ. Для успешной интеграции Command Registry с MCPProxy:
1017
-
1018
- 1. **Установите MCPProxy**:
1019
-
1020
- ```bash
1021
- pip install mcp-proxy
1022
- ```
1023
-
1024
- 2. **Включите поддержку MCPProxy в вашем приложении**:
1025
-
1026
- ```python
1027
- from command_registry.adapters import MCPProxyAdapter
1028
- from my_app.registry import registry
1029
-
1030
- # Создаем адаптер для MCPProxy
1031
- mcp_adapter = MCPProxyAdapter(registry)
1032
-
1033
- # Регистрируем в приложении
1034
- app = FastAPI()
1035
- mcp_adapter.register_endpoints(app)
1036
- ```
1037
-
1038
- 3. **Настройте маршрутизацию в MCPProxy**:
1039
-
1040
- ```yaml
1041
- # mcp_proxy_config.yaml
1042
- routes:
1043
- - path: /api/cmd
1044
- type: json_rpc
1045
- schema_url: http://your-api.com/openapi.json
1046
- command_field: method
1047
- params_field: params
1048
- ```
1049
-
1050
- ### Рекомендации для больших проектов
1051
-
1052
- При использовании Command Registry в крупных проектах с MCPProxy:
1053
-
1054
- 1. **Группируйте команды по функциональности**:
1055
- ```python
1056
- # Пример структуры команд
1057
- my_app/
1058
- commands/
1059
- user_commands.py
1060
- data_commands.py
1061
- admin_commands.py
1062
- ```
1063
-
1064
- 2. **Используйте подпроекты** для отдельных доменных областей:
1065
- ```
1066
- my_solution/
1067
- ├── user_service/
1068
- │ └── commands/
1069
- ├── data_service/
1070
- │ └── commands/
1071
- └── admin_service/
1072
- └── commands/
1073
- ```
1074
-
1075
- 3. **Создайте отдельные гибридные схемы** для каждого подпроекта:
1076
- ```python
1077
- # Для каждого подпроекта
1078
- user_registry = CommandRegistry(...)
1079
- user_generator = HybridAPIGenerator(...)
1080
- user_registry.add_generator(user_generator)
1081
- ```
1082
-
1083
- 4. **Объедините схемы при необходимости** с помощью агрегатора:
1084
- ```python
1085
- from command_registry.tools import SchemaAggregator
1086
-
1087
- aggregator = SchemaAggregator()
1088
- aggregator.add_schema("users", "http://user-service/openapi.json")
1089
- aggregator.add_schema("data", "http://data-service/openapi.json")
1090
- aggregator.add_schema("admin", "http://admin-service/openapi.json")
1091
-
1092
- # Создание единой схемы
1093
- combined_schema = aggregator.generate_combined_schema()
1094
- ```
1095
-
1096
- ### Обновление индекса кода
1097
-
1098
- Для поддержания актуальности документации, обновляйте `code_index.yaml` при изменении структуры проекта:
1099
-
1100
- ```yaml
1101
- # Пример обновления code_index.yaml
1102
- sections:
1103
- - name: "Генераторы"
1104
- description: "Генераторы API схем"
1105
- files:
1106
- - path: "command_registry/generators/hybrid_generator.py"
1107
- description: "Генератор гибридной схемы REST+JSONRPC для MCPProxy"
1108
-
1109
- - name: "Адаптеры"
1110
- description: "Адаптеры для различных протоколов"
1111
- files:
1112
- - path: "command_registry/adapters/mcp_proxy_adapter.py"
1113
- description: "Адаптер для интеграции с MCPProxy"
1114
- ```
1115
-
1116
- Этот подход к организации кода и документации позволит эффективно масштабировать проекты на базе Command Registry и успешно интегрировать их с MCPProxy для создания инструментов моделей ИИ.
1117
-
1118
- # Руководство по публикации в PyPI
1119
-
1120
- В этом руководстве описывается процесс подготовки и публикации пакета MCP Proxy Adapter в Python Package Index (PyPI).
1121
-
1122
- ## Подготовка пакета
1123
-
1124
- ### 1. Обновите метаданные пакета
1125
-
1126
- Перед публикацией убедитесь, что файлы `pyproject.toml` и `setup.py` содержат актуальную информацию:
1127
-
1128
- - Версия пакета
1129
- - Описание
1130
- - URL проекта
1131
- - Адрес электронной почты автора
1132
- - Классификаторы
1133
- - Зависимости
1134
-
1135
- ### 2. Установите необходимые инструменты
1136
-
1137
- ```bash
1138
- pip install build twine
1139
- ```
1140
-
1141
- ### 3. Соберите пакет
1142
-
1143
- ```bash
1144
- python -m build
1145
- ```
1146
-
1147
- Эта команда создаст как Source Distribution (sdist), так и Wheel Distribution (bdist_wheel) в директории `dist/`.
1148
-
1149
- ### 4. Проверьте пакет
1150
-
1151
- ```bash
1152
- twine check dist/*
1153
- ```
1154
-
1155
- Убедитесь, что все проверки пройдены без ошибок.
1156
-
1157
- ## Публикация пакета
1158
-
1159
- ### 1. Настройка аутентификации
1160
-
1161
- Создайте файл `.pypirc` в вашем домашнем каталоге со следующим содержимым:
1162
-
1163
- ```
1164
- [pypi]
1165
- username = __token__
1166
- password = <ваш_токен_pypi>
1167
- ```
1168
-
1169
- Замените `<ваш_токен_pypi>` на ваш токен доступа к PyPI, который вы можете получить в своем аккаунте PyPI.
1170
-
1171
- Альтернативно, вы можете передать учетные данные непосредственно в команду `twine upload`.
1172
-
1173
- ### 2. Публикация в тестовом PyPI (опционально)
1174
-
1175
- Сначала рекомендуется опубликовать пакет в тестовом репозитории:
1176
-
1177
- ```bash
1178
- twine upload --repository-url https://test.pypi.org/legacy/ dist/*
1179
- ```
1180
-
1181
- После этого вы можете установить пакет из тестового PyPI и проверить его работу:
1182
-
1183
- ```bash
1184
- pip install --index-url https://test.pypi.org/simple/ mcp-proxy-adapter
1185
- ```
1186
-
1187
- ### 3. Публикация в основном PyPI
1188
-
1189
- После успешного тестирования опубликуйте пакет в основном PyPI:
1190
-
1191
- ```bash
1192
- twine upload dist/*
1193
- ```
1194
-
1195
- ### 4. Проверка установки
1196
-
1197
- Проверьте, что пакет успешно загружен и может быть установлен:
1198
-
1199
- ```bash
1200
- pip install mcp-proxy-adapter
1201
- ```
1202
-
1203
- ## Обновление пакета
1204
-
1205
- Для публикации новой версии пакета:
1206
-
1207
- 1. Обновите версию в `pyproject.toml` и `setup.py`
1208
- 2. Обновите файл `CHANGELOG.md` (если есть)
1209
- 3. Соберите пакет заново
1210
- 4. Загрузите новую версию в PyPI
1211
-
1212
- ```bash
1213
- # Обновите версию в файлах
1214
- # ...
1215
-
1216
- # Соберите пакет
1217
- python -m build
1218
-
1219
- # Загрузите пакет
1220
- twine upload dist/*
1221
- ```
1222
-
1223
- ## Использование GitHub Actions для автоматической публикации
1224
-
1225
- Вы можете автоматизировать процесс публикации пакета при создании нового релиза в GitHub.
1226
-
1227
- Создайте файл `.github/workflows/publish.yml` со следующим содержимым:
1228
-
1229
- ```yaml
1230
- name: Build and publish Python package
1231
-
1232
- on:
1233
- release:
1234
- types: [created]
1235
-
1236
- jobs:
1237
- deploy:
1238
- runs-on: ubuntu-latest
1239
- steps:
1240
- - uses: actions/checkout@v3
1241
- - name: Set up Python
1242
- uses: actions/setup-python@v4
1243
- with:
1244
- python-version: '3.x'
1245
- - name: Install dependencies
1246
- run: |
1247
- python -m pip install --upgrade pip
1248
- pip install build twine
1249
- - name: Build and publish
1250
- env:
1251
- TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
1252
- TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
1253
- run: |
1254
- python -m build
1255
- twine upload dist/*
1256
- ```
1257
-
1258
- Не забудьте добавить соответствующие секреты `PYPI_USERNAME` и `PYPI_PASSWORD` в настройках вашего GitHub репозитория.
1259
-
1260
- ## Проверка совместимости
1261
-
1262
- Перед публикацией рекомендуется проверить совместимость пакета с различными версиями Python.
1263
- Для этого можно использовать инструмент `tox`:
1264
-
1265
- ```bash
1266
- pip install tox
1267
-
1268
- # Создайте файл tox.ini в корне проекта
1269
- # [tox]
1270
- # envlist = py39, py310, py311, py312
1271
- #
1272
- # [testenv]
1273
- # deps = pytest
1274
- # commands = pytest
1275
-
1276
- # Запустите тесты для разных версий Python
1277
- tox
1278
- ```
1279
-
1280
- ## Документация по установке пакета для пользователей
1281
-
1282
- После публикации пакета в PyPI, пользователи смогут установить его с помощью `pip`:
1283
-
1284
- ```bash
1285
- pip install mcp-proxy-adapter
1286
- ```
1287
-
1288
- Для установки конкретной версии:
1289
-
1290
- ```bash
1291
- pip install mcp-proxy-adapter==1.0.0
1292
- ```
1293
-
1294
- Для обновления до последней версии:
1295
-
1296
- ```bash
1297
- pip install --upgrade mcp-proxy-adapter
1298
- ```