Skip to content

Commit dc17969

Browse files
committed
Add plugin server example
1 parent fa46f3a commit dc17969

7 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## Overview
2+
3+
If you wish to hook up your own plugin server through `dstack` builtin ` rest-plugin`, here's a basic example on how to do so.
4+
5+
## Steps
6+
7+
8+
1. Install required dependencies for the plugin server:
9+
10+
```bash
11+
uv sync
12+
```
13+
14+
1. Start the plugin server locally:
15+
16+
```bash
17+
fastapi dev app/main.py
18+
```
19+
20+
1. Enable `rest-plugin` in `dstack` `server/config.yaml`:
21+
22+
```yaml
23+
plugins:
24+
- rest_plugin
25+
```
26+
27+
1. Point the `dstack` server to your plugin server:
28+
```bash
29+
export DSTACK_PLUGIN_SERVICE_URI=http://127.0.0.1:8000
30+
```

examples/plugins/example_plugin_server/app/__init__.py

Whitespace-only changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import logging
2+
3+
from fastapi import FastAPI
4+
5+
from app.models import FleetSpecRequest, GatewaySpecRequest, RunSpecRequest, VolumeSpecRequest
6+
from app.utils import configure_logging
7+
8+
configure_logging()
9+
logger = logging.getLogger(__name__)
10+
11+
app = FastAPI()
12+
13+
14+
@app.post("/apply_policies/on_run_apply")
15+
async def on_run_apply(request: RunSpecRequest):
16+
logger.info(
17+
f"Received run spec request from user {request.user} and project {request.project}"
18+
)
19+
return request.spec
20+
21+
22+
@app.post("/apply_policies/on_fleet_apply")
23+
async def on_fleet_apply(request: FleetSpecRequest):
24+
logger.info(
25+
f"Received fleet spec request from user {request.user} and project {request.project}"
26+
)
27+
return request.spec
28+
29+
30+
@app.post("/apply_policies/on_volume_apply")
31+
async def on_volume_apply(request: VolumeSpecRequest):
32+
logger.info(
33+
f"Received volume spec request from user {request.user} and project {request.project}"
34+
)
35+
return request.spec
36+
37+
38+
@app.post("/apply_policies/on_gateway_apply")
39+
async def on_gateway_apply(request: GatewaySpecRequest):
40+
logger.info(
41+
f"Received gateway spec request from user {request.user} and project {request.project}"
42+
)
43+
return request.spec
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from typing import Generic, TypeVar
2+
3+
from pydantic import BaseModel
4+
5+
from dstack._internal.core.models.fleets import FleetSpec
6+
from dstack._internal.core.models.gateways import GatewaySpec
7+
from dstack._internal.core.models.runs import RunSpec
8+
from dstack._internal.core.models.volumes import VolumeSpec
9+
10+
SpecType = TypeVar("SpecType", RunSpec, FleetSpec, VolumeSpec, GatewaySpec)
11+
12+
13+
class SpecRequest(BaseModel, Generic[SpecType]):
14+
user: str
15+
project: str
16+
spec: SpecType
17+
18+
19+
RunSpecRequest = SpecRequest[RunSpec]
20+
FleetSpecRequest = SpecRequest[FleetSpec]
21+
VolumeSpecRequest = SpecRequest[VolumeSpec]
22+
GatewaySpecRequest = SpecRequest[GatewaySpec]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import logging
2+
import os
3+
4+
5+
def configure_logging():
6+
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
7+
logging.basicConfig(level=log_level)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "dstack-plugin-server"
3+
version = "0.1.0"
4+
description = "Example plugin server"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"fastapi[standard]>=0.115.12",
9+
"dstack>=0.19.8"
10+
]

0 commit comments

Comments
 (0)