runapi-core 0.1.3__tar.gz → 0.1.5__tar.gz

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 (28) hide show
  1. {runapi_core-0.1.3 → runapi_core-0.1.5}/PKG-INFO +1 -1
  2. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/contract_gen.py +111 -5
  3. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/resource.py +4 -5
  4. runapi_core-0.1.5/src/runapi/core/version.py +1 -0
  5. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_resource.py +11 -0
  6. runapi_core-0.1.3/src/runapi/core/version.py +0 -1
  7. {runapi_core-0.1.3 → runapi_core-0.1.5}/README.md +0 -0
  8. {runapi_core-0.1.3 → runapi_core-0.1.5}/pyproject.toml +0 -0
  9. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/__init__.py +0 -0
  10. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/auth.py +0 -0
  11. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/config.py +0 -0
  12. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/constants.py +0 -0
  13. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/errors.py +0 -0
  14. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/files.py +0 -0
  15. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/http_client.py +0 -0
  16. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/models.py +0 -0
  17. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/multipart.py +0 -0
  18. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/options.py +0 -0
  19. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/polling.py +0 -0
  20. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/py.typed +0 -0
  21. {runapi_core-0.1.3 → runapi_core-0.1.5}/src/runapi/core/response.py +0 -0
  22. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_auth.py +0 -0
  23. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_config.py +0 -0
  24. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_errors.py +0 -0
  25. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_files.py +0 -0
  26. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_http_client.py +0 -0
  27. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_models.py +0 -0
  28. {runapi_core-0.1.3 → runapi_core-0.1.5}/tests/test_polling.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runapi-core
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Core module for the RunAPI Python SDK
5
5
  Project-URL: Homepage, https://runapi.ai
6
6
  Project-URL: Documentation, https://runapi.ai/docs#sdk
@@ -211,7 +211,7 @@ CONTRACT = {
211
211
  }
212
212
  },
213
213
  "grok-imagine/image-to-video": {
214
- "models": ["grok-imagine-image-to-video"],
214
+ "models": ["grok-imagine-image-to-video", "grok-imagine-video-1.5-preview"],
215
215
  "fields_by_model": {
216
216
  "grok-imagine-image-to-video": {
217
217
  "aspect_ratio": {
@@ -223,6 +223,14 @@ CONTRACT = {
223
223
  "output_resolution": {
224
224
  "enum": ["480p", "720p"]
225
225
  }
226
+ },
227
+ "grok-imagine-video-1.5-preview": {
228
+ "aspect_ratio": {
229
+ "enum": ["1:1", "16:9", "9:16", "3:2", "2:3", "auto"]
230
+ },
231
+ "output_resolution": {
232
+ "enum": ["480p", "720p"]
233
+ }
226
234
  }
227
235
  }
228
236
  },
@@ -237,7 +245,7 @@ CONTRACT = {
237
245
  }
238
246
  },
239
247
  "grok-imagine/text-to-video": {
240
- "models": ["grok-imagine-text-to-video"],
248
+ "models": ["grok-imagine-text-to-video", "grok-imagine-video-1.5-preview"],
241
249
  "fields_by_model": {
242
250
  "grok-imagine-text-to-video": {
243
251
  "aspect_ratio": {
@@ -249,6 +257,14 @@ CONTRACT = {
249
257
  "output_resolution": {
250
258
  "enum": ["480p", "720p"]
251
259
  }
260
+ },
261
+ "grok-imagine-video-1.5-preview": {
262
+ "aspect_ratio": {
263
+ "enum": ["1:1", "16:9", "9:16", "3:2", "2:3", "auto"]
264
+ },
265
+ "output_resolution": {
266
+ "enum": ["480p", "720p"]
267
+ }
252
268
  }
253
269
  }
254
270
  },
@@ -508,7 +524,7 @@ CONTRACT = {
508
524
  }
509
525
  },
510
526
  "kling/image-to-video": {
511
- "models": ["kling-v2.1-master-image-to-video", "kling-v2.1-pro", "kling-v2.1-standard", "kling-v2.5-turbo-image-to-video-pro"],
527
+ "models": ["kling-v2.1-master-image-to-video", "kling-v2.1-pro", "kling-v2.1-standard", "kling-v2.5-turbo-image-to-video-pro", "kling-v3-turbo-image-to-video"],
512
528
  "fields_by_model": {
513
529
  "kling-v2.1-master-image-to-video": {
514
530
  "duration_seconds": {
@@ -529,6 +545,14 @@ CONTRACT = {
529
545
  "duration_seconds": {
530
546
  "enum": [5, 10]
531
547
  }
548
+ },
549
+ "kling-v3-turbo-image-to-video": {
550
+ "duration_seconds": {
551
+ "enum": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
552
+ },
553
+ "output_resolution": {
554
+ "enum": ["720p", "1080p"]
555
+ }
532
556
  }
533
557
  }
534
558
  },
@@ -549,7 +573,7 @@ CONTRACT = {
549
573
  }
550
574
  },
551
575
  "kling/text-to-video": {
552
- "models": ["kling-3.0", "kling-v2.1-master-text-to-video", "kling-v2.5-turbo-text-to-video-pro"],
576
+ "models": ["kling-3.0", "kling-v2.1-master-text-to-video", "kling-v2.5-turbo-text-to-video-pro", "kling-v3-turbo-text-to-video"],
553
577
  "fields_by_model": {
554
578
  "kling-3.0": {
555
579
  "aspect_ratio": {
@@ -577,6 +601,17 @@ CONTRACT = {
577
601
  "duration_seconds": {
578
602
  "enum": [5, 10]
579
603
  }
604
+ },
605
+ "kling-v3-turbo-text-to-video": {
606
+ "aspect_ratio": {
607
+ "enum": ["16:9", "9:16", "1:1"]
608
+ },
609
+ "duration_seconds": {
610
+ "enum": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
611
+ },
612
+ "output_resolution": {
613
+ "enum": ["720p", "1080p"]
614
+ }
580
615
  }
581
616
  }
582
617
  },
@@ -586,9 +621,48 @@ CONTRACT = {
586
621
  "luma-modify-video": {}
587
622
  }
588
623
  },
624
+ "midjourney/edit-image": {
625
+ "models": ["midjourney-edit-image"],
626
+ "fields_by_model": {
627
+ "midjourney-edit-image": {}
628
+ }
629
+ },
630
+ "midjourney/get-seed": {
631
+ "models": [],
632
+ "fields_by_model": {
633
+ "_": {}
634
+ }
635
+ },
636
+ "midjourney/image-to-prompt": {
637
+ "models": [],
638
+ "fields_by_model": {
639
+ "_": {}
640
+ }
641
+ },
642
+ "midjourney/image-to-video": {
643
+ "models": ["midjourney-image-to-video"],
644
+ "fields_by_model": {
645
+ "midjourney-image-to-video": {
646
+ "output_resolution": {
647
+ "enum": ["480p"]
648
+ }
649
+ }
650
+ }
651
+ },
652
+ "midjourney/text-to-image": {
653
+ "models": ["midjourney-v8.1"],
654
+ "fields_by_model": {
655
+ "midjourney-v8.1": {}
656
+ }
657
+ },
589
658
  "nano-banana/edit-image": {
590
- "models": ["nano-banana-edit"],
659
+ "models": ["nano-banana-2-lite", "nano-banana-edit"],
591
660
  "fields_by_model": {
661
+ "nano-banana-2-lite": {
662
+ "aspect_ratio": {
663
+ "enum": ["1:1", "1:4", "1:8", "2:3", "3:2", "3:4", "4:1", "4:3", "4:5", "5:4", "8:1", "9:16", "16:9", "21:9", "auto"]
664
+ }
665
+ },
592
666
  "nano-banana-edit": {
593
667
  "aspect_ratio": {
594
668
  "enum": ["1:1", "9:16", "16:9", "3:4", "4:3", "3:2", "2:3", "5:4", "4:5", "21:9", "auto"]
@@ -639,6 +713,28 @@ CONTRACT = {
639
713
  }
640
714
  }
641
715
  },
716
+ "omnihuman/audio-to-video": {
717
+ "models": ["omnihuman-1.5"],
718
+ "fields_by_model": {
719
+ "omnihuman-1.5": {
720
+ "output_resolution": {
721
+ "enum": ["720p", "1080p"]
722
+ }
723
+ }
724
+ }
725
+ },
726
+ "omnihuman/human-identification": {
727
+ "models": ["omnihuman-1.5-human-identification"],
728
+ "fields_by_model": {
729
+ "omnihuman-1.5-human-identification": {}
730
+ }
731
+ },
732
+ "omnihuman/subject-detection": {
733
+ "models": ["omnihuman-1.5-subject-detection"],
734
+ "fields_by_model": {
735
+ "omnihuman-1.5-subject-detection": {}
736
+ }
737
+ },
642
738
  "qwen-2/edit-image": {
643
739
  "models": ["qwen-2-edit-image"],
644
740
  "fields_by_model": {
@@ -1350,6 +1446,16 @@ CONTRACT = {
1350
1446
  }
1351
1447
  }
1352
1448
  },
1449
+ "volcengine-lip-sync/lip-sync-video": {
1450
+ "models": ["volcengine-lip-sync"],
1451
+ "fields_by_model": {
1452
+ "volcengine-lip-sync": {
1453
+ "mode": {
1454
+ "enum": ["lite", "basic"]
1455
+ }
1456
+ }
1457
+ }
1458
+ },
1353
1459
  "wan/animate": {
1354
1460
  "models": ["wan-2.2-animate-move", "wan-2.2-animate-replace"],
1355
1461
  "fields_by_model": {
@@ -59,8 +59,8 @@ class Resource:
59
59
 
60
60
  # ---- Contract validation -------------------------------------------
61
61
  # Validates request params against the generated contract: model
62
- # membership, then per-field required/enum/integer/min/max/length, then
63
- # declared cross-field rules. `schema` is one action entry from the generated
62
+ # membership, then declared cross-field rules, then per-field
63
+ # required/enum/integer/min/max/length. `schema` is one action entry from the generated
64
64
  # per-package CONTRACT (CONTRACT["<action>"]).
65
65
 
66
66
  def _validate_contract(self, schema: Dict[str, Any], params: Dict[str, Any]) -> None:
@@ -73,11 +73,10 @@ class Resource:
73
73
  else:
74
74
  fields = schema.get("fields_by_model", {}).get("_", {})
75
75
 
76
- for field, rules in fields.items():
77
- self._validate_schema_field(params, field, rules)
78
-
79
76
  for rule in schema.get("rules", []):
80
77
  self._enforce_rule(params, rule)
78
+ for field, rules in fields.items():
79
+ self._validate_schema_field(params, field, rules)
81
80
 
82
81
  def _validate_schema_field(self, params: Dict[str, Any], field: str, rules: Dict[str, Any]) -> None:
83
82
  present = self._field_present(params, field)
@@ -0,0 +1 @@
1
+ __version__ = "0.1.5"
@@ -135,6 +135,17 @@ def test_validate_integer_rejects_bool_and_whole_float():
135
135
  assert _run_validate({"model": "m", "tolerance": 5}) == ""
136
136
 
137
137
 
138
+ def test_validate_contract_runs_rules_before_field_requirements():
139
+ schema = {
140
+ "models": ["m"],
141
+ "rules": [{"when": {"model": "m"}, "forbidden": ["source_task_id"]}],
142
+ "fields_by_model": {"m": {"source_image_urls": {"required": True}}},
143
+ }
144
+ resource = SampleResource(FakeHttp())
145
+ with pytest.raises(ValidationError, match="source_task_id is not allowed when model is m"):
146
+ resource._validate_contract(schema, {"model": "m", "source_task_id": "src_1"})
147
+
148
+
138
149
  def test_poll_recoerces_to_completed_class():
139
150
  resource = SampleResource(FakeHttp())
140
151
  response = TaskResponse({"id": "1", "status": "completed", "images": [{"url": "u"}]})
@@ -1 +0,0 @@
1
- __version__ = "0.1.3"
File without changes
File without changes