Metadata-Version: 2.4
Name: nemo-platform
Version: 0.1.0.dev20260516041901
Summary: Convenience wrapper distribution for NeMo Platform Python packages
Author: NVIDIA Corporation
Requires-Python: >=3.11
Requires-Dist: nemo-platform[nemo-platform-plugin]
Requires-Dist: nemo-platform[nemo-platform-sdk]
Requires-Dist: nemo-platform[nmp-common]
Provides-Extra: aiohttp
Requires-Dist: aiohttp; extra == 'aiohttp'
Requires-Dist: httpx-aiohttp>=0.1.9; extra == 'aiohttp'
Provides-Extra: auditor-service
Requires-Dist: aiohttp>=3.13.4; extra == 'auditor-service'
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'auditor-service'
Requires-Dist: nemo-platform[auditor-service] ; extra == "auditor-service"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == 'auditor-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "auditor-service"
Requires-Dist: pydantic-settings>=2.6.1; extra == 'auditor-service'
Requires-Dist: pydantic>=2.10.3; extra == 'auditor-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'auditor-service'
Requires-Dist: requests<3.0.0,>=2.32.3; extra == 'auditor-service'
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'auditor-service'
Requires-Dist: xdg-base-dirs>=6.0.1; extra == 'auditor-service'
Provides-Extra: auth-service
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'auth-service'
Requires-Dist: httpx>=0.27.0; extra == 'auth-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "auth-service"
Requires-Dist: pydantic-settings>=2.6.1; extra == 'auth-service'
Requires-Dist: pydantic>=2.10.3; extra == 'auth-service'
Requires-Dist: pyyaml>=6.0.0; extra == 'auth-service'
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'auth-service'
Requires-Dist: wasmtime>=20.0.0; extra == 'auth-service'
Provides-Extra: builtin-nemo-agent
Requires-Dist: deepagents; extra == 'builtin-nemo-agent'
Requires-Dist: langchain-core; extra == 'builtin-nemo-agent'
Requires-Dist: langchain-openai; extra == 'builtin-nemo-agent'
Requires-Dist: nvidia-nat-core; extra == 'builtin-nemo-agent'
Provides-Extra: core-service
Requires-Dist: aioboto3>=15.5.0; extra == 'core-service'
Requires-Dist: aiohttp>=3.13.4; extra == 'core-service'
Requires-Dist: aiohttp[speedups]>=3.13.4; extra == 'core-service'
Requires-Dist: aiosqlite>=0.20.0; extra == 'core-service'
Requires-Dist: alembic>=1.13.1; extra == 'core-service'
Requires-Dist: anyio>=4.0.0; extra == 'core-service'
Requires-Dist: asyncpg>=0.31.0; extra == 'core-service'
Requires-Dist: base58>=2.1.0; extra == 'core-service'
Requires-Dist: base58>=2.1.1; extra == 'core-service'
Requires-Dist: docker>=7.1.0; extra == 'core-service'
Requires-Dist: duckdb<2.0.0,>=1.1.3; extra == 'core-service'
Requires-Dist: duckdb>=1.1.3; extra == 'core-service'
Requires-Dist: fastapi>=0.100.0; extra == 'core-service'
Requires-Dist: fastapi>=0.115.8; extra == 'core-service'
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'core-service'
Requires-Dist: fastmcp>=3.2.0; extra == 'core-service'
Requires-Dist: greenlet>=3.0.0; extra == 'core-service'
Requires-Dist: httpx>=0.27.0; extra == 'core-service'
Requires-Dist: hvac>=2.3.0; extra == 'core-service'
Requires-Dist: kubernetes>=30.1.0; extra == 'core-service'
Requires-Dist: kubernetes>=31.0.0; extra == 'core-service'
Requires-Dist: lark>=1.1.0; extra == 'core-service'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "core-service"
Requires-Dist: nemo-platform[nemo-platform-sdk] ; extra == "core-service"
Requires-Dist: ngcsdk>=4.9.10; extra == 'core-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "core-service"
Requires-Dist: opentelemetry-proto>=1.28.2; extra == 'core-service'
Requires-Dist: pandas>=1.5.3; extra == 'core-service'
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'core-service'
Requires-Dist: pydantic-settings>=2.0.0; extra == 'core-service'
Requires-Dist: pydantic-settings>=2.6.1; extra == 'core-service'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'core-service'
Requires-Dist: pydantic>=2.0.0; extra == 'core-service'
Requires-Dist: pydantic>=2.10.3; extra == 'core-service'
Requires-Dist: pydantic>=2.10.6; extra == 'core-service'
Requires-Dist: pyyaml>=6.0.0; extra == 'core-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'core-service'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'core-service'
Requires-Dist: sqlmodel>=0.0.22; extra == 'core-service'
Requires-Dist: streaming-form-data>=1.19.1; extra == 'core-service'
Requires-Dist: tenacity>=8.5.0; extra == 'core-service'
Requires-Dist: types-aioboto3[s3]>=15.5.0; extra == 'core-service'
Requires-Dist: urllib3>=2.7.0; extra == 'core-service'
Requires-Dist: uvicorn>=0.34.0; extra == 'core-service'
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'core-service'
Requires-Dist: uvicorn[standard]>=0.23.0; extra == 'core-service'
Requires-Dist: wasmtime>=20.0.0; extra == 'core-service'
Provides-Extra: customizer-service
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'customizer-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "customizer-service"
Requires-Dist: pydantic-settings>=2.6.1; extra == 'customizer-service'
Requires-Dist: pydantic>=2.10.3; extra == 'customizer-service'
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'customizer-service'
Provides-Extra: data-designer-nemo
Requires-Dist: anyio>=4.0; extra == 'data-designer-nemo'
Requires-Dist: data-designer==0.5.7; extra == 'data-designer-nemo'
Requires-Dist: duckdb; extra == 'data-designer-nemo'
Requires-Dist: pydantic>=2; extra == 'data-designer-nemo'
Provides-Extra: entities-service
Requires-Dist: alembic>=1.13.1; extra == 'entities-service'
Requires-Dist: asyncpg>=0.31.0; extra == 'entities-service'
Requires-Dist: base58>=2.1.0; extra == 'entities-service'
Requires-Dist: fastapi>=0.100.0; extra == 'entities-service'
Requires-Dist: fastmcp>=3.2.0; extra == 'entities-service'
Requires-Dist: greenlet>=3.0.0; extra == 'entities-service'
Requires-Dist: lark>=1.1.0; extra == 'entities-service'
Requires-Dist: nemo-platform[nemo-platform-sdk] ; extra == "entities-service"
Requires-Dist: nemo-platform[nmp-common] ; extra == "entities-service"
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'entities-service'
Requires-Dist: pydantic-settings>=2.0.0; extra == 'entities-service'
Requires-Dist: pydantic>=2.0.0; extra == 'entities-service'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'entities-service'
Requires-Dist: uvicorn[standard]>=0.23.0; extra == 'entities-service'
Provides-Extra: evaluator
Requires-Dist: jinja2>=3.1.6; extra == 'evaluator'
Requires-Dist: jsonpath-ng>=1.7.0; extra == 'evaluator'
Requires-Dist: jsonschema>=4.23.0; extra == 'evaluator'
Requires-Dist: openai>=1.61.0; extra == 'evaluator'
Requires-Dist: pandas>=1.5.3; extra == 'evaluator'
Requires-Dist: pyarrow>=19.0.1; extra == 'evaluator'
Requires-Dist: pydantic>=2.10.6; extra == 'evaluator'
Requires-Dist: rouge-score==0.1.2; extra == 'evaluator'
Requires-Dist: sacrebleu>=2.5.1; extra == 'evaluator'
Provides-Extra: evaluator-service
Requires-Dist: aiofiles==24.1.0; extra == 'evaluator-service'
Requires-Dist: aiohttp>=3.13.4; extra == 'evaluator-service'
Requires-Dist: alembic<2.0.0,>=1.13.1; extra == 'evaluator-service'
Requires-Dist: base58<3.0.0,>=2.1.1; extra == 'evaluator-service'
Requires-Dist: datasets>=3.3.1; extra == 'evaluator-service'
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'evaluator-service'
Requires-Dist: huggingface-hub>=0.34.0; extra == 'evaluator-service'
Requires-Dist: jsonpath-ng>=1.6.0; extra == 'evaluator-service'
Requires-Dist: kubernetes>=31.0.0; extra == 'evaluator-service'
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.0.0; extra == 'evaluator-service'
Requires-Dist: nemo-platform[evaluator] ; extra == "evaluator-service"
Requires-Dist: nemo-platform[nmp-common] ; extra == "evaluator-service"
Requires-Dist: openai>=1.61.0; extra == 'evaluator-service'
Requires-Dist: opentelemetry-distro<1.0,>=0.48b0; extra == 'evaluator-service'
Requires-Dist: opentelemetry-exporter-otlp>=1.27.0; extra == 'evaluator-service'
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.9; extra == 'evaluator-service'
Requires-Dist: pydantic-settings>=2.6.1; extra == 'evaluator-service'
Requires-Dist: pydantic>=2.10.3; extra == 'evaluator-service'
Requires-Dist: pymilvus==2.6.12; extra == 'evaluator-service'
Requires-Dist: python-box>=7.3.2; extra == 'evaluator-service'
Requires-Dist: ragas==0.3.5; extra == 'evaluator-service'
Requires-Dist: requests<3.0.0,>=2.31.0; extra == 'evaluator-service'
Requires-Dist: sqlmodel<1.0.0,>=0.0.14; extra == 'evaluator-service'
Requires-Dist: starlette<1.0.0,>=0.52.1; extra == 'evaluator-service'
Requires-Dist: uvicorn<1.0.0.0,>=0.24.0-post.0; extra == 'evaluator-service'
Provides-Extra: files-service
Requires-Dist: aioboto3>=15.5.0; extra == 'files-service'
Requires-Dist: aiohttp>=3.13.4; extra == 'files-service'
Requires-Dist: anyio>=4.0.0; extra == 'files-service'
Requires-Dist: duckdb>=1.1.3; extra == 'files-service'
Requires-Dist: fastapi>=0.115.8; extra == 'files-service'
Requires-Dist: ngcsdk>=4.9.10; extra == 'files-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "files-service"
Requires-Dist: opentelemetry-proto>=1.28.2; extra == 'files-service'
Requires-Dist: pandas>=1.5.3; extra == 'files-service'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'files-service'
Requires-Dist: pydantic>=2.10.6; extra == 'files-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'files-service'
Requires-Dist: streaming-form-data>=1.19.1; extra == 'files-service'
Requires-Dist: types-aioboto3[s3]>=15.5.0; extra == 'files-service'
Requires-Dist: uvicorn>=0.34.0; extra == 'files-service'
Provides-Extra: guardrails-service
Requires-Dist: alembic<2.0.0,>=1.10.4; extra == 'guardrails-service'
Requires-Dist: fastapi>=0.109.0; extra == 'guardrails-service'
Requires-Dist: fsspec>=2024.10.0; extra == 'guardrails-service'
Requires-Dist: gunicorn>=23.0.0; extra == 'guardrails-service'
Requires-Dist: httpx>=0.27.2; extra == 'guardrails-service'
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.0.0; extra == 'guardrails-service'
Requires-Dist: langchain-openai<2.0.0,>=1.0.0; extra == 'guardrails-service'
Requires-Dist: nemoguardrails[tracing]~=0.21.0; extra == 'guardrails-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "guardrails-service"
Requires-Dist: openai>=1.61.0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-distro>=0.41b0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-exporter-otlp>=1.22.0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.48b0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-instrumentation-httpx>=0.48b0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-instrumentation-requests>=0.48b0; extra == 'guardrails-service'
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.27.0; extra == 'guardrails-service'
Requires-Dist: pydantic-settings>=2.2.1; extra == 'guardrails-service'
Requires-Dist: python-multipart~=0.0.9; extra == 'guardrails-service'
Requires-Dist: requests>=2.31.0; extra == 'guardrails-service'
Requires-Dist: uvicorn>=0.32.1; extra == 'guardrails-service'
Requires-Dist: yara-python==4.5.1; extra == 'guardrails-service'
Provides-Extra: hello-world-service
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'hello-world-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "hello-world-service"
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'hello-world-service'
Provides-Extra: inference-gateway-service
Requires-Dist: aiohttp[speedups]>=3.13.4; extra == 'inference-gateway-service'
Requires-Dist: fastapi>=0.115.8; extra == 'inference-gateway-service'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "inference-gateway-service"
Requires-Dist: nemo-platform[nmp-common] ; extra == "inference-gateway-service"
Requires-Dist: pydantic-settings>=2.8.1; extra == 'inference-gateway-service'
Requires-Dist: pydantic>=2.10.6; extra == 'inference-gateway-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'inference-gateway-service'
Requires-Dist: uvicorn>=0.34.0; extra == 'inference-gateway-service'
Provides-Extra: intake-service
Requires-Dist: alembic<2.0.0,>=1.10.4; extra == 'intake-service'
Requires-Dist: asyncpg<1.0.0,>=0.30.0; extra == 'intake-service'
Requires-Dist: base58>=2.1.1; extra == 'intake-service'
Requires-Dist: celery>=5.5.3; extra == 'intake-service'
Requires-Dist: clickhouse-connect<1.0,>=0.7; extra == 'intake-service'
Requires-Dist: fastapi<1.0.0,>=0.115.5; extra == 'intake-service'
Requires-Dist: flower>=2.0.1; extra == 'intake-service'
Requires-Dist: httpx<1.0.0,>=0.24.1; extra == 'intake-service'
Requires-Dist: huggingface-hub<1.0.0,>=0.26.2; extra == 'intake-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "intake-service"
Requires-Dist: openai>=1.51.0; extra == 'intake-service'
Requires-Dist: opentelemetry-api>=1.27.0; extra == 'intake-service'
Requires-Dist: opentelemetry-exporter-otlp>=1.27.0; extra == 'intake-service'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.48b0; extra == 'intake-service'
Requires-Dist: opentelemetry-instrumentation-openai>=0.33.9; extra == 'intake-service'
Requires-Dist: opentelemetry-proto>=1.27.0; extra == 'intake-service'
Requires-Dist: opentelemetry-sdk>=1.27.0; extra == 'intake-service'
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'intake-service'
Requires-Dist: pydantic-settings<3.0.0,>=2.6.1; extra == 'intake-service'
Requires-Dist: pydantic<3.0.0,>=2.9.2; extra == 'intake-service'
Requires-Dist: python-dotenv<2.0.0,>=1.0.0; extra == 'intake-service'
Requires-Dist: pyyaml<7.0.0,>=6.0.2; extra == 'intake-service'
Requires-Dist: redis>=5.0.1; extra == 'intake-service'
Requires-Dist: requests<3.0.0,>=2.32.3; extra == 'intake-service'
Requires-Dist: sqlalchemy>=2.0; extra == 'intake-service'
Requires-Dist: types-requests<3.0.0.0,>=2.32.0.20241016; extra == 'intake-service'
Requires-Dist: uvicorn<1.0.0,>=0.22.0; extra == 'intake-service'
Requires-Dist: watchdog[watchmedo]>=6.0.0; extra == 'intake-service'
Provides-Extra: jobs-service
Requires-Dist: aiosqlite>=0.20.0; extra == 'jobs-service'
Requires-Dist: base58>=2.1.1; extra == 'jobs-service'
Requires-Dist: docker>=7.1.0; extra == 'jobs-service'
Requires-Dist: duckdb<2.0.0,>=1.1.3; extra == 'jobs-service'
Requires-Dist: fastapi>=0.115.8; extra == 'jobs-service'
Requires-Dist: hvac>=2.3.0; extra == 'jobs-service'
Requires-Dist: kubernetes>=30.1.0; extra == 'jobs-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "jobs-service"
Requires-Dist: pandas>=1.5.3; extra == 'jobs-service'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'jobs-service'
Requires-Dist: pydantic>=2.10.6; extra == 'jobs-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'jobs-service'
Requires-Dist: sqlmodel>=0.0.22; extra == 'jobs-service'
Requires-Dist: uvicorn>=0.34.0; extra == 'jobs-service'
Provides-Extra: models-service
Requires-Dist: docker>=7.1.0; extra == 'models-service'
Requires-Dist: fastapi>=0.115.8; extra == 'models-service'
Requires-Dist: kubernetes>=31.0.0; extra == 'models-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "models-service"
Requires-Dist: pydantic-settings>=2.8.1; extra == 'models-service'
Requires-Dist: pydantic>=2.10.6; extra == 'models-service'
Requires-Dist: pyyaml>=6.0.2; extra == 'models-service'
Requires-Dist: sqlmodel>=0.0.22; extra == 'models-service'
Requires-Dist: tenacity>=8.5.0; extra == 'models-service'
Requires-Dist: urllib3>=2.7.0; extra == 'models-service'
Requires-Dist: uvicorn>=0.34.0; extra == 'models-service'
Provides-Extra: nemo-agents-plugin
Requires-Dist: anthropic>=0.88.0; extra == 'nemo-agents-plugin'
Requires-Dist: nemo-platform[builtin-nemo-agent] ; extra == "nemo-agents-plugin"
Requires-Dist: httpx>=0.27; extra == 'nemo-agents-plugin'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-agents-plugin"
Requires-Dist: nemo-platform[nmp-common] ; extra == "nemo-agents-plugin"
Requires-Dist: nvidia-nat-core; extra == 'nemo-agents-plugin'
Requires-Dist: nvidia-nat-eval; extra == 'nemo-agents-plugin'
Requires-Dist: nvidia-nat-langchain; extra == 'nemo-agents-plugin'
Requires-Dist: pyyaml>=6.0; extra == 'nemo-agents-plugin'
Requires-Dist: rich>=13.7.1; extra == 'nemo-agents-plugin'
Provides-Extra: nemo-anonymizer-plugin
Requires-Dist: nemo-platform[data-designer-nemo] ; extra == "nemo-anonymizer-plugin"
Requires-Dist: data-designer==0.5.7; extra == 'nemo-anonymizer-plugin'
Requires-Dist: fastapi; extra == 'nemo-anonymizer-plugin'
Requires-Dist: httpx>=0.27; extra == 'nemo-anonymizer-plugin'
Requires-Dist: nemo-anonymizer>=0.1.0; extra == 'nemo-anonymizer-plugin'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-anonymizer-plugin"
Requires-Dist: nemo-platform[nmp-common] ; extra == "nemo-anonymizer-plugin"
Requires-Dist: pandas; extra == 'nemo-anonymizer-plugin'
Requires-Dist: pyyaml>=6.0; extra == 'nemo-anonymizer-plugin'
Provides-Extra: nemo-auditor-plugin
Requires-Dist: nemo-platform[auditor-service] ; extra == "nemo-auditor-plugin"
Requires-Dist: httpx>=0.27; extra == 'nemo-auditor-plugin'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-auditor-plugin"
Requires-Dist: pydantic>=2.10.6; extra == 'nemo-auditor-plugin'
Requires-Dist: pyyaml>=6.0; extra == 'nemo-auditor-plugin'
Requires-Dist: typer>=0.12.5; extra == 'nemo-auditor-plugin'
Provides-Extra: nemo-data-designer-plugin
Requires-Dist: nemo-platform[data-designer-nemo] ; extra == "nemo-data-designer-plugin"
Requires-Dist: data-designer==0.5.7; extra == 'nemo-data-designer-plugin'
Requires-Dist: duckdb; extra == 'nemo-data-designer-plugin'
Requires-Dist: fastapi; extra == 'nemo-data-designer-plugin'
Requires-Dist: httpx>=0.27; extra == 'nemo-data-designer-plugin'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-data-designer-plugin"
Requires-Dist: nemo-platform[nmp-common] ; extra == "nemo-data-designer-plugin"
Requires-Dist: pandas; extra == 'nemo-data-designer-plugin'
Provides-Extra: nemo-evaluator-plugin
Requires-Dist: nemo-platform[evaluator] ; extra == "nemo-evaluator-plugin"
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-evaluator-plugin"
Requires-Dist: nemo-platform[evaluator-service] ; extra == "nemo-evaluator-plugin"
Requires-Dist: pydantic>=2.10.6; extra == 'nemo-evaluator-plugin'
Requires-Dist: typer>=0.12.5; extra == 'nemo-evaluator-plugin'
Provides-Extra: nemo-guardrails-plugin
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-guardrails-plugin"
Requires-Dist: nemoguardrails[tracing]==0.21.0; extra == 'nemo-guardrails-plugin'
Provides-Extra: nemo-platform-plugin
Requires-Dist: anthropic>=0.88.0; extra == 'nemo-platform-plugin'
Requires-Dist: fastapi>=0.115.4; extra == 'nemo-platform-plugin'
Requires-Dist: nemo-platform[nemo-platform-sdk] ; extra == "nemo-platform-plugin"
Requires-Dist: openai>=1.109.1; extra == 'nemo-platform-plugin'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'nemo-platform-plugin'
Requires-Dist: pydantic>=2.10.3; extra == 'nemo-platform-plugin'
Requires-Dist: pyyaml>=6.0.2; extra == 'nemo-platform-plugin'
Requires-Dist: typer>=0.20.0; extra == 'nemo-platform-plugin'
Provides-Extra: nemo-platform-sdk
Requires-Dist: anyio<5,>=4.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: distro<2,>=1.7.0; extra == 'nemo-platform-sdk'
Requires-Dist: docker>=7.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: fsspec>=2023.1.0; extra == 'nemo-platform-sdk'
Requires-Dist: httpx<1,>=0.23.0; extra == 'nemo-platform-sdk'
Requires-Dist: ngcsdk>=4.8.2; extra == 'nemo-platform-sdk'
Requires-Dist: nvidia-ml-py>=13.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: openai; extra == 'nemo-platform-sdk'
Requires-Dist: prompt-toolkit>=3.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: psutil>=5.9.0; extra == 'nemo-platform-sdk'
Requires-Dist: pydantic<3,>=2.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: pyyaml>=6.0.0; extra == 'nemo-platform-sdk'
Requires-Dist: requests>=2.31.0; extra == 'nemo-platform-sdk'
Requires-Dist: rich>=13.7.1; extra == 'nemo-platform-sdk'
Requires-Dist: sniffio; extra == 'nemo-platform-sdk'
Requires-Dist: typer>=0.20.0; extra == 'nemo-platform-sdk'
Requires-Dist: typing-extensions<5,>=4.14; extra == 'nemo-platform-sdk'
Provides-Extra: nemo-switchyard
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nemo-switchyard"
Requires-Dist: nemo-platform[switchyard] ; extra == "nemo-switchyard"
Provides-Extra: nmp-common
Requires-Dist: aiofiles>=24.1.0; extra == 'nmp-common'
Requires-Dist: base58>=2.1.1; extra == 'nmp-common'
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'nmp-common'
Requires-Dist: huggingface-hub>=0.34.0; extra == 'nmp-common'
Requires-Dist: hvac>=2.3.0; extra == 'nmp-common'
Requires-Dist: kubernetes>=30.1.0; extra == 'nmp-common'
Requires-Dist: lark>=1.1.0; extra == 'nmp-common'
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "nmp-common"
Requires-Dist: nemo-platform[nemo-platform-sdk] ; extra == "nmp-common"
Requires-Dist: nvidia-ml-py>=13.0.0; extra == 'nmp-common'
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.38.0; extra == 'nmp-common'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.38.0; extra == 'nmp-common'
Requires-Dist: opentelemetry-exporter-prometheus>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-instrumentation-httpx>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-instrumentation-system-metrics>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-processor-baggage>=0.59b0; extra == 'nmp-common'
Requires-Dist: opentelemetry-sdk>=1.38.0; extra == 'nmp-common'
Requires-Dist: prometheus-client>=0.23.0; extra == 'nmp-common'
Requires-Dist: prometheus-fastapi-instrumentator>=7.1.0; extra == 'nmp-common'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'nmp-common'
Requires-Dist: pydantic>=2.10.3; extra == 'nmp-common'
Requires-Dist: pyjwt[crypto]>=2.12.0; extra == 'nmp-common'
Requires-Dist: pyyaml>=6.0.2; extra == 'nmp-common'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'nmp-common'
Requires-Dist: structlog>=24.1.0; extra == 'nmp-common'
Provides-Extra: plugins
Requires-Dist: anthropic>=0.88.0; extra == 'plugins'
Requires-Dist: nemo-platform[builtin-nemo-agent] ; extra == "plugins"
Requires-Dist: nemo-platform[data-designer-nemo] ; extra == "plugins"
Requires-Dist: data-designer==0.5.7; extra == 'plugins'
Requires-Dist: deepagents; extra == 'plugins'
Requires-Dist: duckdb; extra == 'plugins'
Requires-Dist: fastapi; extra == 'plugins'
Requires-Dist: nemo-platform[auditor-service] ; extra == "plugins"
Requires-Dist: httpx>=0.27; extra == 'plugins'
Requires-Dist: langchain-core; extra == 'plugins'
Requires-Dist: langchain-openai; extra == 'plugins'
Requires-Dist: nemo-anonymizer>=0.1.0; extra == 'plugins'
Requires-Dist: nemo-platform[evaluator] ; extra == "plugins"
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "plugins"
Requires-Dist: nemoguardrails[tracing]==0.21.0; extra == 'plugins'
Requires-Dist: nemo-platform[nmp-common] ; extra == "plugins"
Requires-Dist: nemo-platform[evaluator-service] ; extra == "plugins"
Requires-Dist: nvidia-nat-core; extra == 'plugins'
Requires-Dist: nvidia-nat-eval; extra == 'plugins'
Requires-Dist: nvidia-nat-langchain; extra == 'plugins'
Requires-Dist: pandas; extra == 'plugins'
Requires-Dist: pydantic>=2.10.6; extra == 'plugins'
Requires-Dist: pyyaml>=6.0; extra == 'plugins'
Requires-Dist: rich>=13.7.1; extra == 'plugins'
Requires-Dist: nemo-platform[switchyard] ; extra == "plugins"
Requires-Dist: typer>=0.12.5; extra == 'plugins'
Provides-Extra: safe-synthesizer
Requires-Dist: pandas>=1.5.3; extra == 'safe-synthesizer'
Provides-Extra: safe-synthesizer-service
Requires-Dist: fastapi>=0.115.8; extra == 'safe-synthesizer-service'
Requires-Dist: fsspec>=2024.10.0; extra == 'safe-synthesizer-service'
Requires-Dist: gunicorn>=23.0.0; extra == 'safe-synthesizer-service'
Requires-Dist: httpx>=0.27.2; extra == 'safe-synthesizer-service'
Requires-Dist: nemo-safe-synthesizer; extra == 'safe-synthesizer-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "safe-synthesizer-service"
Requires-Dist: opentelemetry-distro>=0.41b; extra == 'safe-synthesizer-service'
Requires-Dist: opentelemetry-exporter-otlp>=1.22.0; extra == 'safe-synthesizer-service'
Requires-Dist: pydantic-settings>=2.2.1; extra == 'safe-synthesizer-service'
Requires-Dist: pydantic[email]>=2.9.2; extra == 'safe-synthesizer-service'
Requires-Dist: python-multipart~=0.0.9; extra == 'safe-synthesizer-service'
Requires-Dist: requests>=2.31.0; extra == 'safe-synthesizer-service'
Requires-Dist: uvicorn>=0.32.1; extra == 'safe-synthesizer-service'
Provides-Extra: secrets-service
Requires-Dist: fastapi>=0.115.8; extra == 'secrets-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "secrets-service"
Requires-Dist: uvicorn>=0.34.0; extra == 'secrets-service'
Provides-Extra: services
Requires-Dist: aioboto3>=15.5.0; extra == 'services'
Requires-Dist: aiofiles==24.1.0; extra == 'services'
Requires-Dist: aiohttp>=3.13.4; extra == 'services'
Requires-Dist: aiohttp[speedups]>=3.13.4; extra == 'services'
Requires-Dist: aiosqlite>=0.20.0; extra == 'services'
Requires-Dist: alembic<2.0.0,>=1.10.4; extra == 'services'
Requires-Dist: alembic<2.0.0,>=1.13.1; extra == 'services'
Requires-Dist: alembic>=1.13.1; extra == 'services'
Requires-Dist: anthropic>=0.88.0; extra == 'services'
Requires-Dist: anyio>=4.0.0; extra == 'services'
Requires-Dist: asyncpg<1.0.0,>=0.30.0; extra == 'services'
Requires-Dist: asyncpg>=0.31.0; extra == 'services'
Requires-Dist: base58<3.0.0,>=2.1.1; extra == 'services'
Requires-Dist: base58>=2.1.0; extra == 'services'
Requires-Dist: base58>=2.1.1; extra == 'services'
Requires-Dist: nemo-platform[builtin-nemo-agent] ; extra == "services"
Requires-Dist: celery>=5.5.3; extra == 'services'
Requires-Dist: clickhouse-connect<1.0,>=0.7; extra == 'services'
Requires-Dist: nemo-platform[data-designer-nemo] ; extra == "services"
Requires-Dist: data-designer==0.5.7; extra == 'services'
Requires-Dist: datasets>=3.3.1; extra == 'services'
Requires-Dist: deepagents; extra == 'services'
Requires-Dist: docker>=7.1.0; extra == 'services'
Requires-Dist: duckdb; extra == 'services'
Requires-Dist: duckdb<2.0.0,>=1.1.3; extra == 'services'
Requires-Dist: duckdb>=1.1.3; extra == 'services'
Requires-Dist: fastapi; extra == 'services'
Requires-Dist: fastapi<1.0.0,>=0.115.5; extra == 'services'
Requires-Dist: fastapi>=0.100.0; extra == 'services'
Requires-Dist: fastapi>=0.109.0; extra == 'services'
Requires-Dist: fastapi>=0.115.8; extra == 'services'
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'services'
Requires-Dist: fastmcp>=3.2.0; extra == 'services'
Requires-Dist: flower>=2.0.1; extra == 'services'
Requires-Dist: fsspec>=2024.10.0; extra == 'services'
Requires-Dist: nemo-platform[auditor-service] ; extra == "services"
Requires-Dist: greenlet>=3.0.0; extra == 'services'
Requires-Dist: gunicorn>=23.0.0; extra == 'services'
Requires-Dist: httpx<1.0.0,>=0.24.1; extra == 'services'
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == 'services'
Requires-Dist: httpx>=0.27; extra == 'services'
Requires-Dist: httpx>=0.27.0; extra == 'services'
Requires-Dist: httpx>=0.27.2; extra == 'services'
Requires-Dist: huggingface-hub<1.0.0,>=0.26.2; extra == 'services'
Requires-Dist: huggingface-hub>=0.34.0; extra == 'services'
Requires-Dist: hvac>=2.3.0; extra == 'services'
Requires-Dist: jsonpath-ng>=1.6.0; extra == 'services'
Requires-Dist: kubernetes>=30.1.0; extra == 'services'
Requires-Dist: kubernetes>=31.0.0; extra == 'services'
Requires-Dist: langchain-core; extra == 'services'
Requires-Dist: langchain-nvidia-ai-endpoints<2.0.0,>=1.0.0; extra == 'services'
Requires-Dist: langchain-openai; extra == 'services'
Requires-Dist: langchain-openai<2.0.0,>=1.0.0; extra == 'services'
Requires-Dist: lark>=1.1.0; extra == 'services'
Requires-Dist: nemo-anonymizer>=0.1.0; extra == 'services'
Requires-Dist: nemo-platform[evaluator] ; extra == "services"
Requires-Dist: nemo-platform[nemo-platform-plugin] ; extra == "services"
Requires-Dist: nemo-platform[nemo-platform-sdk] ; extra == "services"
Requires-Dist: nemo-safe-synthesizer; extra == 'services'
Requires-Dist: nemoguardrails[tracing]==0.21.0; extra == 'services'
Requires-Dist: nemoguardrails[tracing]~=0.21.0; extra == 'services'
Requires-Dist: ngcsdk>=4.9.10; extra == 'services'
Requires-Dist: nemo-platform[nmp-common] ; extra == "services"
Requires-Dist: nemo-platform[evaluator-service] ; extra == "services"
Requires-Dist: nvidia-nat-core; extra == 'services'
Requires-Dist: nvidia-nat-eval; extra == 'services'
Requires-Dist: nvidia-nat-langchain; extra == 'services'
Requires-Dist: openai>=1.51.0; extra == 'services'
Requires-Dist: openai>=1.61.0; extra == 'services'
Requires-Dist: opentelemetry-api>=1.27.0; extra == 'services'
Requires-Dist: opentelemetry-distro<1.0,>=0.48b0; extra == 'services'
Requires-Dist: opentelemetry-distro>=0.41b; extra == 'services'
Requires-Dist: opentelemetry-distro>=0.41b0; extra == 'services'
Requires-Dist: opentelemetry-exporter-otlp>=1.22.0; extra == 'services'
Requires-Dist: opentelemetry-exporter-otlp>=1.27.0; extra == 'services'
Requires-Dist: opentelemetry-instrumentation-fastapi>=0.48b0; extra == 'services'
Requires-Dist: opentelemetry-instrumentation-httpx>=0.48b0; extra == 'services'
Requires-Dist: opentelemetry-instrumentation-openai>=0.33.9; extra == 'services'
Requires-Dist: opentelemetry-instrumentation-requests>=0.48b0; extra == 'services'
Requires-Dist: opentelemetry-proto>=1.27.0; extra == 'services'
Requires-Dist: opentelemetry-proto>=1.28.2; extra == 'services'
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.27.0; extra == 'services'
Requires-Dist: opentelemetry-sdk>=1.27.0; extra == 'services'
Requires-Dist: pandas; extra == 'services'
Requires-Dist: pandas>=1.5.3; extra == 'services'
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.9; extra == 'services'
Requires-Dist: psycopg2-binary>=2.9.10; extra == 'services'
Requires-Dist: pydantic-settings<3.0.0,>=2.6.1; extra == 'services'
Requires-Dist: pydantic-settings>=2.0.0; extra == 'services'
Requires-Dist: pydantic-settings>=2.2.1; extra == 'services'
Requires-Dist: pydantic-settings>=2.6.1; extra == 'services'
Requires-Dist: pydantic-settings>=2.8.1; extra == 'services'
Requires-Dist: pydantic<3.0.0,>=2.9.2; extra == 'services'
Requires-Dist: pydantic>=2.0.0; extra == 'services'
Requires-Dist: pydantic>=2.10.3; extra == 'services'
Requires-Dist: pydantic>=2.10.6; extra == 'services'
Requires-Dist: pydantic[email]>=2.9.2; extra == 'services'
Requires-Dist: pyleak>=0.1.0; extra == 'services'
Requires-Dist: pymilvus==2.6.12; extra == 'services'
Requires-Dist: python-box>=7.3.2; extra == 'services'
Requires-Dist: python-dotenv<2.0.0,>=1.0.0; extra == 'services'
Requires-Dist: python-multipart~=0.0.9; extra == 'services'
Requires-Dist: pyyaml<7.0.0,>=6.0.2; extra == 'services'
Requires-Dist: pyyaml>=6.0; extra == 'services'
Requires-Dist: pyyaml>=6.0.0; extra == 'services'
Requires-Dist: pyyaml>=6.0.2; extra == 'services'
Requires-Dist: ragas==0.3.5; extra == 'services'
Requires-Dist: redis>=5.0.1; extra == 'services'
Requires-Dist: requests<3.0.0,>=2.31.0; extra == 'services'
Requires-Dist: requests<3.0.0,>=2.32.3; extra == 'services'
Requires-Dist: requests>=2.31.0; extra == 'services'
Requires-Dist: rich>=13.7.1; extra == 'services'
Requires-Dist: rich>=14.1.0; extra == 'services'
Requires-Dist: sqlalchemy>=2.0; extra == 'services'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'services'
Requires-Dist: sqlmodel<1.0.0,>=0.0.14; extra == 'services'
Requires-Dist: sqlmodel>=0.0.22; extra == 'services'
Requires-Dist: starlette<1.0.0,>=0.52.1; extra == 'services'
Requires-Dist: streaming-form-data>=1.19.1; extra == 'services'
Requires-Dist: nemo-platform[switchyard] ; extra == "services"
Requires-Dist: tenacity>=8.5.0; extra == 'services'
Requires-Dist: typer>=0.12.5; extra == 'services'
Requires-Dist: types-aioboto3[s3]>=15.5.0; extra == 'services'
Requires-Dist: types-requests<3.0.0.0,>=2.32.0.20241016; extra == 'services'
Requires-Dist: urllib3>=2.7.0; extra == 'services'
Requires-Dist: uvicorn<1.0.0,>=0.22.0; extra == 'services'
Requires-Dist: uvicorn<1.0.0.0,>=0.24.0-post.0; extra == 'services'
Requires-Dist: uvicorn>=0.32.1; extra == 'services'
Requires-Dist: uvicorn>=0.34.0; extra == 'services'
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'services'
Requires-Dist: uvicorn[standard]>=0.23.0; extra == 'services'
Requires-Dist: wasmtime>=20.0.0; extra == 'services'
Requires-Dist: watchdog[watchmedo]>=6.0.0; extra == 'services'
Requires-Dist: xdg-base-dirs>=6.0.1; extra == 'services'
Requires-Dist: yara-python==4.5.1; extra == 'services'
Provides-Extra: studio-service
Requires-Dist: fastapi[standard]>=0.115.4; extra == 'studio-service'
Requires-Dist: nemo-platform[nmp-common] ; extra == "studio-service"
Requires-Dist: uvicorn[standard]>=0.12.0; extra == 'studio-service'
Provides-Extra: switchyard
Requires-Dist: anthropic<1.0,>=0.99.0; extra == 'switchyard'
Requires-Dist: httpx<1.0,>=0.28.1; extra == 'switchyard'
Requires-Dist: openai<3.0,>=2.34.0; extra == 'switchyard'
Requires-Dist: pydantic<3.0,>=2.13.3; extra == 'switchyard'
Description-Content-Type: text/markdown

# nemo-platform

Wrapper distribution for NeMo Platform. When users run `pip install nemo-platform`, this is the wheel they get.

The wheel bundles the SDK, shared runtime packages, default first-party plugins, and services directly from source via hatch force-include. As sub-packages are published independently to PyPI, they'll be removed from the bundle and added as normal dependencies instead.

## How bundling works

All source bundling is configured in `pyproject.toml` via `[tool.bundle-package]`. Each entry declares a package source tree to include in the wheel:

```toml
[tool.bundle-package]
nemo-platform-plugin = { source = "../../packages/nemo_platform_plugin/src/nemo_platform_plugin", module = "nemo_platform_plugin" }
nemo-platform-sdk = { source = "../../sdk/python/nemo-platform/src/nemo_platform", module = "nemo_platform", inherit = { "optional-dependencies" = true, scripts = true } }
nemo-auditor-plugin = { source = "../../plugins/nemo-auditor/src/nemo_auditor", module = "nemo_auditor", inherit = { "entry-points" = ["nemo.*"] } }
nmp-auth = { source = "../../services/core/auth/src/nmp/core/auth", module = "nmp/core/auth", deps_group = "auth-service" }
```

Each entry has:
- **key** — the distribution/package name used to find its `pyproject.toml`, read its metadata, and match wheel `Requires-Dist` entries
- **source** — relative path to the source directory to include in the wheel
- **module** — target module path inside the wheel
- **deps_group** (optional) — name of the `[project.optional-dependencies]` group where the package's transitive deps are written. Defaults to the bundle key.
- **inherit** (optional) — structured metadata to re-export from the bundled package. Supported keys are `scripts`, `entry-points`, and `optional-dependencies`; each value is either `true` or a list of wildcard patterns.
- **scripts** (optional) — explicit CLI entrypoints to register on the wrapper. Prefer `inherit.scripts` when copying scripts from the bundled package.

By default, bundled package metadata is not re-exported. `nemo-platform` opts into SDK scripts and SDK optional dependencies, and it opts into only `nemo.*` entry-point groups from the default first-party plugins. Other plugin entry-point groups, such as `data_designer.plugins`, are intentionally not inherited.

Two tools read this config:

### `hatch_build.py` (build hook)

At wheel build time, the build hook reads `[tool.bundle-package]` and generates hatch force-include mappings dynamically. It merges those mappings with static `[tool.hatch.build.targets.wheel.force-include]` entries for non-package assets such as alembic migrations and Studio UI static files.

During editable installs (`uv sync`), the build hook does nothing. Workspace packages resolve via their normal editable/workspace installation, so there is no copied bundle and the source dependency graph stays intact.

After the wheel is built, the build hook opens the wheel, rewrites `METADATA`, regenerates `RECORD`, and repacks the wheel. Any `Requires-Dist` whose distribution name matches a `[tool.bundle-package]` key is rewritten to a self-referencing extra using that entry's `deps_group`, or the bundle key when `deps_group` is omitted. Existing requirement extras and environment markers are preserved.

For example, this source dependency:

```text
Requires-Dist: nmp-common
```

becomes this in the final wheel metadata:

```text
Requires-Dist: nemo-platform[nmp-common]
```

A dependency with extras and a marker, such as `nemo-platform-sdk[aiohttp] ; python_version >= "3.11"`, becomes `nemo-platform[nemo-platform-sdk,aiohttp] ; python_version >= "3.11"`.

### `make vendor` (vendor tool)

The vendor tool resets generated wrapper metadata before rebuilding it, so stale generated extras, scripts, and entry-point tables do not persist across runs. Generated sections are annotated with `# Generated from [tool.bundle-package]; do not edit by hand.`.

The `_process_bundle_packages()` phase in `vendor_package.py` reads `[tool.bundle-package]` from every workspace package that has one. For each entry it:

1. Finds the bundled package's `pyproject.toml`, using the configured `source` path when needed
2. Reads its `[project.dependencies]`
3. Filters out workspace packages that are not bundled by the parent, because they are not installable from PyPI
4. Keeps bundled workspace dependency names readable in source metadata, so the wheel build hook can rewrite final `Requires-Dist` metadata to self-extras
5. Writes the resulting deps into the generated extra named by `deps_group`, or by the bundle key when `deps_group` is omitted
6. Copies only the metadata explicitly selected by `inherit`
7. Writes any explicit `scripts = [...]` declared directly on the bundle entry

For the wrapper specifically, `make vendor` also creates aggregate extras from `[tool.bundle-package]`:

- `core-service` references all core service `*-service` extras.
- `plugins` references all bundled first-party plugin extras whose source lives under `plugins/*/src`.
- `services` references `core-service`, all non-core service `*-service` extras, and `plugins`.

## Dependency groups

The wrapper's `[project.dependencies]` is hand-written with the true workspace dependencies for the base install:

```toml
dependencies = [
  "nemo-platform-sdk",
  "nmp-common",
  "nemo-platform-plugin",
]
```

Those direct workspace dependencies are what editable installs and repo-local tooling see. Wheel builds rewrite them to self-referencing extras so published wheels do not require unpublished workspace packages:

```toml
dependencies = [
  "nemo-platform[nemo-platform-sdk]",
  "nemo-platform[nmp-common]",
  "nemo-platform[nemo-platform-plugin]",
]
```

Service and plugin dependencies are behind optional extras. They are composed via:
- `auth-service`, `entities-service`, etc. — individual service deps
- `core-service` — aggregates all core service `-service` extras
- `plugins` — aggregates default first-party plugin extras
- `services` — aggregates `core-service`, all non-core service `-service` extras, and `plugins`

The `services` extra includes `plugins` because Python entry points are distribution-level metadata and are not conditional on extras. If the wrapper publishes plugin `nemo.services` entry points, installing service discovery dependencies must also install the plugin dependencies needed by those entry points.

The `[project.optional-dependencies]` section is **auto-generated** by `make vendor`. Do not edit it by hand. The wheel rewrite step assumes those generated `deps_group` extras already exist before the build starts.

The wrapper's generated `[project.scripts]` currently re-exports only the SDK CLI entry points:

```toml
[project.scripts]
nemo = "nemo_platform.cli.app:cli"
nmp = "nemo_platform.cli.app:cli"
```

Service-specific server scripts are not exposed by the umbrella `nemo-platform` wheel. Individual service packages may still expose their own scripts, and the wrapper uses `nemo services run` through the platform runner instead.

## Extracting a package to PyPI

To publish a bundled package independently:

1. Remove its entry from `[tool.bundle-package]`
2. Add it as a normal dependency in `[project.dependencies]` (or in the appropriate optional group)
3. Run `make vendor` to regenerate the dependency groups

The wheel gets thinner, the dependency metadata stays correct, and `pip install nemo-platform` continues to work.

## Other vendoring (`make vendor`)

The `make vendor` command also handles SDK client extensions (`nemo_platform_ext`, `data_designer_sdk`, `models`, `filesets`, `safe_synthesizer_sdk`, `nemo_evaluator_sdk`). These are **not** bundled via `[tool.bundle-package]` — they use the older `[tool.vendor-package]` mechanism which copies source files into the SDK tree with import rewriting. This is separate from the bundling described above and is only relevant to SDK client-side extensions.
