Skip to content

Commit 734d509

Browse files
authored
Fix run calls for versions with invalid Cog version (#165)
Fixes #163 --------- Signed-off-by: Mattt Zmuda <mattt@replicate.com>
1 parent 6b548ee commit 734d509

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

replicate/schema.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1+
from typing import Optional
2+
13
from packaging import version
24

35
# TODO: this code is shared with replicate's backend. Maybe we should put it in the Cog Python package as the source of truth?
46

57

6-
def version_has_no_array_type(cog_version: str) -> bool:
8+
def version_has_no_array_type(cog_version: str) -> Optional[bool]:
79
"""Iterators have x-cog-array-type=iterator in the schema from 0.3.9 onward"""
8-
return version.parse(cog_version) < version.parse("0.3.9")
10+
try:
11+
return version.parse(cog_version) < version.parse("0.3.9")
12+
except version.InvalidVersion:
13+
return None
914

1015

1116
def make_schema_backwards_compatible(
1217
schema: dict,
1318
version: str,
1419
) -> dict:
1520
"""A place to add backwards compatibility logic for our openapi schema"""
21+
1622
# If the top-level output is an array, assume it is an iterator in old versions which didn't have an array type
1723
if version_has_no_array_type(version):
1824
output = schema["components"]["schemas"]["Output"]

tests/test_run.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
import httpx
12
import pytest
3+
import respx
24

35
import replicate
6+
from replicate.client import Client
47
from replicate.exceptions import ReplicateError
58

69

@@ -31,3 +34,90 @@ async def test_run(mock_replicate_api_token):
3134
def test_run_with_invalid_identifier(mock_replicate_api_token):
3235
with pytest.raises(ReplicateError):
3336
replicate.run("invalid")
37+
38+
39+
@pytest.mark.asyncio
40+
async def test_run_version_with_invalid_cog_version(mock_replicate_api_token):
41+
def prediction_with_status(status: str) -> dict:
42+
return {
43+
"id": "p1",
44+
"version": "v1",
45+
"urls": {
46+
"get": "https://api.replicate.com/v1/predictions/p1",
47+
"cancel": "https://api.replicate.com/v1/predictions/p1/cancel",
48+
},
49+
"created_at": "2023-10-05T12:00:00.000000Z",
50+
"source": "api",
51+
"status": status,
52+
"input": {"text": "world"},
53+
"output": "Hello, world!" if status == "succeeded" else None,
54+
"error": None,
55+
"logs": "",
56+
}
57+
58+
router = respx.Router(base_url="https://api.replicate.com/v1")
59+
router.route(method="POST", path="/predictions").mock(
60+
return_value=httpx.Response(
61+
201,
62+
json=prediction_with_status("running"),
63+
)
64+
)
65+
router.route(method="GET", path="/predictions/p1").mock(
66+
return_value=httpx.Response(
67+
200,
68+
json=prediction_with_status("succeeded"),
69+
)
70+
)
71+
router.route(
72+
method="GET",
73+
path="/models/test/example/versions/invalid",
74+
).mock(
75+
return_value=httpx.Response(
76+
201,
77+
json={
78+
"id": "f2d6b24e6002f25f77ae89c2b0a5987daa6d0bf751b858b94b8416e8542434d1",
79+
"created_at": "2022-03-16T00:35:56.210272Z",
80+
"cog_version": "dev",
81+
"openapi_schema": {
82+
"openapi": "3.0.2",
83+
"info": {"title": "Cog", "version": "0.1.0"},
84+
"paths": {},
85+
"components": {
86+
"schemas": {
87+
"Input": {
88+
"type": "object",
89+
"title": "Input",
90+
"required": ["text"],
91+
"properties": {
92+
"text": {
93+
"type": "string",
94+
"title": "Text",
95+
"x-order": 0,
96+
"description": "The text input",
97+
},
98+
},
99+
},
100+
"Output": {
101+
"type": "string",
102+
"title": "Output",
103+
},
104+
}
105+
},
106+
},
107+
},
108+
)
109+
)
110+
router.route(host="api.replicate.com").pass_through()
111+
112+
client = Client(
113+
api_token="test-token", transport=httpx.MockTransport(router.handler)
114+
)
115+
116+
output = client.run(
117+
"test/example:invalid",
118+
input={
119+
"text": "Hello, world!",
120+
},
121+
)
122+
123+
assert output == "Hello, world!"

0 commit comments

Comments
 (0)