Skip to content

Commit a2e03fa

Browse files
committed
model injection working
1 parent 77e79a8 commit a2e03fa

6 files changed

Lines changed: 71 additions & 7 deletions

File tree

api/src/models/dataset.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use uuid::Uuid;
66
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
77
pub struct Dataset {
88
pub id: Uuid,
9-
pub project_id: Uuid,
9+
pub project_id: Option<Uuid>,
1010
pub name: String,
1111
pub description: Option<String>,
1212
pub format: String,
@@ -45,7 +45,7 @@ pub struct UploadUrlResponse {
4545
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
4646
pub struct DataSource {
4747
pub id: Uuid,
48-
pub project_id: Uuid,
48+
pub project_id: Option<Uuid>,
4949
pub name: String,
5050
pub source_type: String,
5151
pub connection_string: Option<String>,

api/src/models/model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use uuid::Uuid;
66
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
77
pub struct Model {
88
pub id: Uuid,
9-
pub project_id: Uuid,
9+
pub project_id: Option<Uuid>,
1010
pub name: String,
1111
pub description: Option<String>,
1212
pub framework: String,

api/src/models/pipeline.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use uuid::Uuid;
66
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
77
pub struct Pipeline {
88
pub id: Uuid,
9-
pub project_id: Uuid,
9+
pub project_id: Option<Uuid>,
1010
pub name: String,
1111
pub description: Option<String>,
1212
pub config: serde_json::Value,

api/src/routes/sdk.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@ pub async fn create_sweep(
13741374
Json(req): Json<CreateSweepRequest>,
13751375
) -> AppResult<Json<serde_json::Value>> {
13761376
let model = resolve_model_id(&state.db, &req.model_id).await?;
1377-
let project_id = req.project_id.unwrap_or(model.project_id);
1377+
let project_id = req.project_id.or(model.project_id);
13781378

13791379
let dataset_id = if let Some(ref ds) = req.dataset_id {
13801380
Some(resolve_dataset_id(&state.db, ds).await?)

sdk/python/openmodelstudio/registry.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ def registry_install(name: str, registry_url: str = None, models_dir: str = None
154154
_api_url = api_url or os.environ.get("OPENMODELSTUDIO_API_URL") or _load_api_url()
155155
_token = token or os.environ.get("OPENMODELSTUDIO_TOKEN")
156156

157+
# Auto-detect local platform if no api_url is configured
158+
if not _api_url:
159+
_api_url = _auto_detect_api_url()
160+
161+
# Auto-login if we have an api_url but no token
162+
if _api_url and not _token:
163+
_token = _auto_login(_api_url)
164+
157165
if _api_url:
158166
try:
159167
main_file = files[0]
@@ -196,6 +204,32 @@ def _load_api_url() -> str:
196204
return ""
197205

198206

207+
def _auto_detect_api_url() -> str:
208+
"""Auto-detect local platform API (K8s NodePort at localhost:31001)."""
209+
try:
210+
resp = requests.get("http://localhost:31001/healthz", timeout=2)
211+
if resp.ok:
212+
return "http://localhost:31001"
213+
except Exception:
214+
pass
215+
return ""
216+
217+
218+
def _auto_login(api_url: str) -> str:
219+
"""Auto-login with default credentials to get a token for registration."""
220+
try:
221+
resp = requests.post(
222+
f"{api_url}/auth/login",
223+
json={"email": "test@openmodel.studio", "password": "Test1234"},
224+
timeout=10,
225+
)
226+
if resp.ok:
227+
return resp.json().get("access_token", "")
228+
except Exception:
229+
pass
230+
return ""
231+
232+
199233
def registry_uninstall(name: str, models_dir: str = None,
200234
api_url: str = None, token: str = None) -> bool:
201235
"""Uninstall a locally installed model.
@@ -222,6 +256,10 @@ def registry_uninstall(name: str, models_dir: str = None,
222256
# Also unregister from platform API
223257
_api_url = api_url or os.environ.get("OPENMODELSTUDIO_API_URL") or _load_api_url()
224258
_token = token or os.environ.get("OPENMODELSTUDIO_TOKEN")
259+
if not _api_url:
260+
_api_url = _auto_detect_api_url()
261+
if _api_url and not _token:
262+
_token = _auto_login(_api_url)
225263
if _api_url:
226264
try:
227265
headers = {"Content-Type": "application/json"}

web/src/app/registry/[id]/page.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
Package,
1515
ArrowLeft,
1616
Download,
17+
Trash2,
1718
User,
1819
Tag,
1920
ExternalLink,
@@ -219,6 +220,16 @@ export default function RegistryModelDetailPage() {
219220
}
220221
};
221222

223+
const handleUninstall = async () => {
224+
try {
225+
await api.post("/models/registry-uninstall", { name: modelName });
226+
toast.success(`Uninstalled ${modelName}`);
227+
setIsInstalled(false);
228+
} catch (err) {
229+
toast.error(err instanceof Error ? err.message : "Failed to uninstall");
230+
}
231+
};
232+
222233
const handleCopyInstall = () => {
223234
navigator.clipboard.writeText(`openmodelstudio install ${modelName}`);
224235
setCopied(true);
@@ -294,10 +305,14 @@ export default function RegistryModelDetailPage() {
294305
<Badge variant="secondary" className="bg-muted text-[10px]">
295306
v{model.version}
296307
</Badge>
297-
{isInstalled && (
308+
{isInstalled ? (
298309
<Badge className="bg-emerald-500/10 text-emerald-400 border-emerald-500/20 text-[10px]">
299310
Installed
300311
</Badge>
312+
) : (
313+
<Badge variant="outline" className="text-muted-foreground/50 text-[10px]">
314+
Not Installed
315+
</Badge>
301316
)}
302317
</div>
303318
<div className="flex items-center gap-3 mt-1">
@@ -324,12 +339,23 @@ export default function RegistryModelDetailPage() {
324339
</Button>
325340
</motion.div>
326341
)}
342+
{isInstalled && (
343+
<motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.97 }}>
344+
<Button
345+
variant="outline"
346+
className="gap-2 border-red-500/30 text-red-400 hover:bg-red-500/10 hover:text-red-300"
347+
onClick={handleUninstall}
348+
>
349+
<Trash2 className="h-4 w-4" /> Uninstall
350+
</Button>
351+
</motion.div>
352+
)}
327353
<motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.97 }}>
328354
<Button
329355
className="gap-2 bg-white text-black hover:bg-white/90 shadow-lg shadow-white/10"
330356
onClick={() => setInstallOpen(true)}
331357
>
332-
<Download className="h-4 w-4" /> {isInstalled ? "Install to Project" : "Install"}
358+
<Download className="h-4 w-4" /> {isInstalled ? "Reinstall" : "Install"}
333359
</Button>
334360
</motion.div>
335361
</div>

0 commit comments

Comments
 (0)