tetra-rp 0.6.0__py3-none-any.whl → 0.24.0__py3-none-any.whl

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 (97) hide show
  1. tetra_rp/__init__.py +109 -19
  2. tetra_rp/cli/commands/__init__.py +1 -0
  3. tetra_rp/cli/commands/apps.py +143 -0
  4. tetra_rp/cli/commands/build.py +1082 -0
  5. tetra_rp/cli/commands/build_utils/__init__.py +1 -0
  6. tetra_rp/cli/commands/build_utils/handler_generator.py +176 -0
  7. tetra_rp/cli/commands/build_utils/lb_handler_generator.py +309 -0
  8. tetra_rp/cli/commands/build_utils/manifest.py +430 -0
  9. tetra_rp/cli/commands/build_utils/mothership_handler_generator.py +75 -0
  10. tetra_rp/cli/commands/build_utils/scanner.py +596 -0
  11. tetra_rp/cli/commands/deploy.py +580 -0
  12. tetra_rp/cli/commands/init.py +123 -0
  13. tetra_rp/cli/commands/resource.py +108 -0
  14. tetra_rp/cli/commands/run.py +296 -0
  15. tetra_rp/cli/commands/test_mothership.py +458 -0
  16. tetra_rp/cli/commands/undeploy.py +533 -0
  17. tetra_rp/cli/main.py +97 -0
  18. tetra_rp/cli/utils/__init__.py +1 -0
  19. tetra_rp/cli/utils/app.py +15 -0
  20. tetra_rp/cli/utils/conda.py +127 -0
  21. tetra_rp/cli/utils/deployment.py +530 -0
  22. tetra_rp/cli/utils/ignore.py +143 -0
  23. tetra_rp/cli/utils/skeleton.py +184 -0
  24. tetra_rp/cli/utils/skeleton_template/.env.example +4 -0
  25. tetra_rp/cli/utils/skeleton_template/.flashignore +40 -0
  26. tetra_rp/cli/utils/skeleton_template/.gitignore +44 -0
  27. tetra_rp/cli/utils/skeleton_template/README.md +263 -0
  28. tetra_rp/cli/utils/skeleton_template/main.py +44 -0
  29. tetra_rp/cli/utils/skeleton_template/mothership.py +55 -0
  30. tetra_rp/cli/utils/skeleton_template/pyproject.toml +58 -0
  31. tetra_rp/cli/utils/skeleton_template/requirements.txt +1 -0
  32. tetra_rp/cli/utils/skeleton_template/workers/__init__.py +0 -0
  33. tetra_rp/cli/utils/skeleton_template/workers/cpu/__init__.py +19 -0
  34. tetra_rp/cli/utils/skeleton_template/workers/cpu/endpoint.py +36 -0
  35. tetra_rp/cli/utils/skeleton_template/workers/gpu/__init__.py +19 -0
  36. tetra_rp/cli/utils/skeleton_template/workers/gpu/endpoint.py +61 -0
  37. tetra_rp/client.py +136 -33
  38. tetra_rp/config.py +29 -0
  39. tetra_rp/core/api/runpod.py +591 -39
  40. tetra_rp/core/deployment.py +232 -0
  41. tetra_rp/core/discovery.py +425 -0
  42. tetra_rp/core/exceptions.py +50 -0
  43. tetra_rp/core/resources/__init__.py +27 -9
  44. tetra_rp/core/resources/app.py +738 -0
  45. tetra_rp/core/resources/base.py +139 -4
  46. tetra_rp/core/resources/constants.py +21 -0
  47. tetra_rp/core/resources/cpu.py +115 -13
  48. tetra_rp/core/resources/gpu.py +182 -16
  49. tetra_rp/core/resources/live_serverless.py +153 -16
  50. tetra_rp/core/resources/load_balancer_sls_resource.py +440 -0
  51. tetra_rp/core/resources/network_volume.py +126 -31
  52. tetra_rp/core/resources/resource_manager.py +436 -35
  53. tetra_rp/core/resources/serverless.py +537 -120
  54. tetra_rp/core/resources/serverless_cpu.py +201 -0
  55. tetra_rp/core/resources/template.py +1 -59
  56. tetra_rp/core/utils/constants.py +10 -0
  57. tetra_rp/core/utils/file_lock.py +260 -0
  58. tetra_rp/core/utils/http.py +67 -0
  59. tetra_rp/core/utils/lru_cache.py +75 -0
  60. tetra_rp/core/utils/singleton.py +36 -1
  61. tetra_rp/core/validation.py +44 -0
  62. tetra_rp/execute_class.py +301 -0
  63. tetra_rp/protos/remote_execution.py +98 -9
  64. tetra_rp/runtime/__init__.py +1 -0
  65. tetra_rp/runtime/circuit_breaker.py +274 -0
  66. tetra_rp/runtime/config.py +12 -0
  67. tetra_rp/runtime/exceptions.py +49 -0
  68. tetra_rp/runtime/generic_handler.py +206 -0
  69. tetra_rp/runtime/lb_handler.py +189 -0
  70. tetra_rp/runtime/load_balancer.py +160 -0
  71. tetra_rp/runtime/manifest_fetcher.py +192 -0
  72. tetra_rp/runtime/metrics.py +325 -0
  73. tetra_rp/runtime/models.py +73 -0
  74. tetra_rp/runtime/mothership_provisioner.py +512 -0
  75. tetra_rp/runtime/production_wrapper.py +266 -0
  76. tetra_rp/runtime/reliability_config.py +149 -0
  77. tetra_rp/runtime/retry_manager.py +118 -0
  78. tetra_rp/runtime/serialization.py +124 -0
  79. tetra_rp/runtime/service_registry.py +346 -0
  80. tetra_rp/runtime/state_manager_client.py +248 -0
  81. tetra_rp/stubs/live_serverless.py +35 -17
  82. tetra_rp/stubs/load_balancer_sls.py +357 -0
  83. tetra_rp/stubs/registry.py +145 -19
  84. {tetra_rp-0.6.0.dist-info → tetra_rp-0.24.0.dist-info}/METADATA +398 -60
  85. tetra_rp-0.24.0.dist-info/RECORD +99 -0
  86. {tetra_rp-0.6.0.dist-info → tetra_rp-0.24.0.dist-info}/WHEEL +1 -1
  87. tetra_rp-0.24.0.dist-info/entry_points.txt +2 -0
  88. tetra_rp/core/pool/cluster_manager.py +0 -177
  89. tetra_rp/core/pool/dataclass.py +0 -18
  90. tetra_rp/core/pool/ex.py +0 -38
  91. tetra_rp/core/pool/job.py +0 -22
  92. tetra_rp/core/pool/worker.py +0 -19
  93. tetra_rp/core/resources/utils.py +0 -50
  94. tetra_rp/core/utils/json.py +0 -33
  95. tetra_rp-0.6.0.dist-info/RECORD +0 -39
  96. /tetra_rp/{core/pool → cli}/__init__.py +0 -0
  97. {tetra_rp-0.6.0.dist-info → tetra_rp-0.24.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
1
+ tetra_rp/__init__.py,sha256=SMc8Yhv2uiN8bj6N0crQkgIxpzNyGb4m6JsHX7Wx8Z0,3561
2
+ tetra_rp/client.py,sha256=cK0T2GF4P9cHdPdKbwoaXEWMCvP3n2La9aPjRe7afac,7386
3
+ tetra_rp/config.py,sha256=9FYzouOam0PVoBIITpwHu1N5dGd1ueLHjWMaZYmdquI,760
4
+ tetra_rp/execute_class.py,sha256=a-k6nfOdksuw--BDZ5Au4asJ2eHwbClg9B3YmkPITvg,11480
5
+ tetra_rp/logger.py,sha256=gk5-PWp3k_GQ5DxndsRkBCX0jarp_3lgZ1oiTFuThQg,1125
6
+ tetra_rp/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ tetra_rp/cli/main.py,sha256=farGvK-zRvqRyT-HUMZPMRo-8DOQBHe-tsn24sGpVHs,2623
8
+ tetra_rp/cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
9
+ tetra_rp/cli/commands/apps.py,sha256=qO6UCpRgv_wqQmLo0AmMNCzctP4OpQQ4I9zUUOpBeRM,4765
10
+ tetra_rp/cli/commands/build.py,sha256=VxUOnHRZ84GxFYUaje0QyjPRbNpHJhNQUZLwNkqxbQk,38431
11
+ tetra_rp/cli/commands/deploy.py,sha256=Ehx7XDVPO1WGOFGu7eNsmxrz9Mz1DPJh93Og3pFP9RA,19278
12
+ tetra_rp/cli/commands/init.py,sha256=VK-noKJqdl-ua49-mEx6Vo72aLspiTxX16QmHVfNsJo,4652
13
+ tetra_rp/cli/commands/resource.py,sha256=FWFJh0-O95tc9Byj6vESppuHFC98mmGMOOMc_rohT6s,3183
14
+ tetra_rp/cli/commands/run.py,sha256=z1-YD4zAjplsFreTSaLaiPMqBSPXayDbpQ7XvzZn77k,9199
15
+ tetra_rp/cli/commands/test_mothership.py,sha256=9fbzc5AmIMYg-161-NlJdiZWcg-oDr0ocIqmhuOXNmk,15817
16
+ tetra_rp/cli/commands/undeploy.py,sha256=0NWvdkS6Hb1KKx649TITJQKVOQSFX9g0Q0NKIbPZgJk,17646
17
+ tetra_rp/cli/commands/build_utils/__init__.py,sha256=3-JRo6x364rQNvBVtodjazltU5kRfT5q9uygZG4RvOE,52
18
+ tetra_rp/cli/commands/build_utils/handler_generator.py,sha256=-55rk0QYGbZjlI9t-r5PvsfgMfH0rj5fTVLwOanSISM,6051
19
+ tetra_rp/cli/commands/build_utils/lb_handler_generator.py,sha256=3ZrjX3HQ6HkLR5BLBSimtHXVXdYeGm_bCRoy0lSvyw0,10972
20
+ tetra_rp/cli/commands/build_utils/manifest.py,sha256=7eYQYqwa7W5KuKklh8HjbXBaFEVft1cM411yo5esZiE,17928
21
+ tetra_rp/cli/commands/build_utils/mothership_handler_generator.py,sha256=pNIGxuxmGUQ_UWrfY5-0NudFFuB5WZ3Rf1XxiYpNBOM,2179
22
+ tetra_rp/cli/commands/build_utils/scanner.py,sha256=4l5avf-yefFJ-ujuZGLB5iJR8xD_GubWVZShCBt4UoQ,24508
23
+ tetra_rp/cli/utils/__init__.py,sha256=Ytcdqe_Kzy37LSnsBj1Drkrx0Uo7TWExjQZ2mwW_nMg,27
24
+ tetra_rp/cli/utils/app.py,sha256=QvgXcU4Rh03df1DMe9Xbo3nCAWc-pOm6UofGsT7pMUg,361
25
+ tetra_rp/cli/utils/conda.py,sha256=Lj_ddXxysAFboR-Hd6wTM-mrV6TBEnQzKhEgxjUQdPo,3514
26
+ tetra_rp/cli/utils/deployment.py,sha256=eB6Fxs6jHM8we9v1jVSOaQZeb4Jzr_3ngKtB-z4qaSA,18476
27
+ tetra_rp/cli/utils/ignore.py,sha256=_xKYhvtvc4AK9jHDzRdA9F6xxGhmySEPgqPCsN7cHdg,3858
28
+ tetra_rp/cli/utils/skeleton.py,sha256=wPEmnE_-wovPIciqdSFT52V6FkU3xOUrNunOosfoAks,5143
29
+ tetra_rp/cli/utils/skeleton_template/.env.example,sha256=NlyPYFfuhVMjPym_cueY1g_AzLfk4UZN3w6sjLoD0RE,93
30
+ tetra_rp/cli/utils/skeleton_template/.flashignore,sha256=tEYF62QjHhxS0AUinT0lREqQ7AykQ3lRn6MWKeo7fow,350
31
+ tetra_rp/cli/utils/skeleton_template/.gitignore,sha256=gzGwh94QgCJTWM3ZJ-cqkgQjnl6XlGwUiZIRxQAugdA,334
32
+ tetra_rp/cli/utils/skeleton_template/README.md,sha256=4GJxkw2jwW4oqJwDX5Bs6VP9njrAqRZXmEkWXnJNaIQ,6691
33
+ tetra_rp/cli/utils/skeleton_template/main.py,sha256=KdmqQ_xCC5CVt6BupgDGAhJicD4Guac7-6hqVq4TC5E,960
34
+ tetra_rp/cli/utils/skeleton_template/mothership.py,sha256=NoBVl_gj5G-LYid_6ys6a-nzX8nraeQorYRhfYwizAg,1422
35
+ tetra_rp/cli/utils/skeleton_template/pyproject.toml,sha256=BK-i8NIETSvGrKRyR-rTHPtPw1SjAt7ls9cYKvP44Rg,1121
36
+ tetra_rp/cli/utils/skeleton_template/requirements.txt,sha256=bBay7JTDwJXsTYvVjrwno9hnF-j0q272lk65f2AcPjU,9
37
+ tetra_rp/cli/utils/skeleton_template/workers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ tetra_rp/cli/utils/skeleton_template/workers/cpu/__init__.py,sha256=IIxdRazQUPPzZOLzCW5-CBs_nA8mum3pReWjpSSI8GI,419
39
+ tetra_rp/cli/utils/skeleton_template/workers/cpu/endpoint.py,sha256=hknYcoQtbTPqTkizXBItJTWlTWOZFuUXfpm7ffhNnpc,948
40
+ tetra_rp/cli/utils/skeleton_template/workers/gpu/__init__.py,sha256=EHavaP1AGbUvY44u0tlykZfe2-dlVKrk4HWtmMw5oeo,419
41
+ tetra_rp/cli/utils/skeleton_template/workers/gpu/endpoint.py,sha256=e9m8how8M6XzYxECJ-DI4PMdGoM62rhyUu_r8vB6RQI,1782
42
+ tetra_rp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ tetra_rp/core/deployment.py,sha256=t1aNBz9KoumBagqak4ad6BMhU4A4X8PSJ_yQyhebejk,7637
44
+ tetra_rp/core/discovery.py,sha256=qFMym-rP_i3MY3JiBjaShlJDI3UTxU1Zl0X03RgshdU,15083
45
+ tetra_rp/core/exceptions.py,sha256=YmsVzrAHx5NdF2styV1g1xqjrDO5ULh9vvciU37iYfo,1572
46
+ tetra_rp/core/validation.py,sha256=r83rezzdSoJSUBIbyjCuSxf2-tBBw0PtBkUFY-djnkI,1145
47
+ tetra_rp/core/api/__init__.py,sha256=oldrEKMwxYoBPLvPfVlaFS3wfUtTTxCN6-HzlpTh6vE,124
48
+ tetra_rp/core/api/runpod.py,sha256=IwV8aGGcTd6qbXTXOeFMQ4fhxPsXp9wACwShPv9Aspo,28744
49
+ tetra_rp/core/resources/__init__.py,sha256=0wcpxF8R-_xaycecAcfm4qln9sFEMyB2rszPCbv-0Ns,1289
50
+ tetra_rp/core/resources/app.py,sha256=P4GY3H5TCRaO5fdUtpEW-FvMr8WMD0I4L0IkJdNjMm4,26968
51
+ tetra_rp/core/resources/base.py,sha256=U_WUm-Z64DFvnzCdvJaptE7VWZDDUH7HehYLztlVSSo,6679
52
+ tetra_rp/core/resources/cloud.py,sha256=XJOWPfzYlDVJGHxgffcfpEaOKrWhGdi7AzTlaGuYj0o,70
53
+ tetra_rp/core/resources/constants.py,sha256=hKUhdEwjG-uPPfnObdVYlis2rEtanTiwewLSJqDL1pU,829
54
+ tetra_rp/core/resources/cpu.py,sha256=Kk7ZDHi7Pv8AgxPujA3FB-ujRQCSubgKDlZfhdQDqKg,3935
55
+ tetra_rp/core/resources/environment.py,sha256=FC9kJCa8YLSar75AKUKqJYnNLrUdjZj8ZTOrspBrS00,1267
56
+ tetra_rp/core/resources/gpu.py,sha256=XvjoldCmREQuurKIXAKKW_OwdZYc5M-3LwZfPLeIMMw,7217
57
+ tetra_rp/core/resources/live_serverless.py,sha256=vfXm-NH7vwhkUqAz5sSb9SG-8cujUPSS-wOHNrcSgwM,5463
58
+ tetra_rp/core/resources/load_balancer_sls_resource.py,sha256=zoJcTicC27szDNctVBI7QxOwvVm22YGVsKD2qv12Q3s,14829
59
+ tetra_rp/core/resources/network_volume.py,sha256=SJUXnYj6RXw05d78leOBTUufGk7cSAObhrZGDjDSRwo,6610
60
+ tetra_rp/core/resources/resource_manager.py,sha256=Ya3L0awgCnCRr1syPhryDPP8BwNN4f8LINll4hh_g1Q,20550
61
+ tetra_rp/core/resources/serverless.py,sha256=uAXTViiHG3fy0ERl1cRRz4YNupEirgB5-dp9kmWxxFk,30288
62
+ tetra_rp/core/resources/serverless_cpu.py,sha256=I5t0IqPI5oFG1VdYRJj-iyI86otrXByZGtytnla30G4,7517
63
+ tetra_rp/core/resources/template.py,sha256=BPZxcI-2UIXIrxrZvogpJLVawBYIzKgb-unn5_-Mw7I,1098
64
+ tetra_rp/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
+ tetra_rp/core/utils/backoff.py,sha256=1pfa0smFNpib8nztcIgBbtrVvQeECKh-aNOfL2TztgU,1324
66
+ tetra_rp/core/utils/constants.py,sha256=Dm4XiO5zTzfdqOSeYVfAjaf2LyHnIEVmbOi_s_k1J_E,375
67
+ tetra_rp/core/utils/file_lock.py,sha256=bxtAexD2rbqMhdr94VbmKdNp0gfKRgxDXx1n7LX4Eso,8269
68
+ tetra_rp/core/utils/http.py,sha256=BjiFup--TTRBILmn1XT3SnIj-Gwr6IeDFXMSAQneuAE,2157
69
+ tetra_rp/core/utils/lru_cache.py,sha256=drwKg-DfLbeBRGTzuxKqNKMQq0EuZV15LMTZIOyZuVk,2618
70
+ tetra_rp/core/utils/singleton.py,sha256=yYarzyuk8uNgh0SygXGuEo9Mvue3y8MmQPD3QtwVIr0,1452
71
+ tetra_rp/protos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ tetra_rp/protos/remote_execution.py,sha256=4UBl3Peyaf53O7LqvAw9rM226CsTJxf6q3AhQiKP9Pg,5438
73
+ tetra_rp/runtime/__init__.py,sha256=jpj1kVQ-SQ4TeOgCFgaUFhZaxVjB3t0mZkEGw6YkEl0,56
74
+ tetra_rp/runtime/circuit_breaker.py,sha256=kN4kPiZ4R611wZb7nMaMDPAsr1fUJsi98FKMz9YkUOE,9570
75
+ tetra_rp/runtime/config.py,sha256=5x9ZMBqtuifux55GbbSUMEz6Q-IV3FjAQlI3s6veJR4,303
76
+ tetra_rp/runtime/exceptions.py,sha256=X6owuVMOofxS_giGsvd0eCIQZMPAwEocAXgxyPrRypM,1005
77
+ tetra_rp/runtime/generic_handler.py,sha256=2Y5CldR1CVMlODlUsOPMdV2ZvTQk8kOw29gGT5BopfM,6167
78
+ tetra_rp/runtime/lb_handler.py,sha256=JAJEQDy1OZLSfwz-TlJgYrZiovLtLxiwX-NiEp7wGdE,7175
79
+ tetra_rp/runtime/load_balancer.py,sha256=_8hOLvq2Ilvotnb6eO-0rBSQ6H1-zEGJA1ptVxcdDoQ,5274
80
+ tetra_rp/runtime/manifest_fetcher.py,sha256=AjBNZX2jtE7Cfc7fqX-1M2ghFEzac4OqY4mrvbh-Kxs,6361
81
+ tetra_rp/runtime/metrics.py,sha256=fssrZ74of4FqatuwMV6a6eYmgNcIDfk_wCUHYnLfhY0,9229
82
+ tetra_rp/runtime/models.py,sha256=KZXLIPqDmbR07mYhOZHxGE6HjyQhHYqepnEHUPpNU_Y,2135
83
+ tetra_rp/runtime/mothership_provisioner.py,sha256=zbC9p6LRAQfsOtAygcSc4gQ9kdccQscWqRxXr6X_5-A,18327
84
+ tetra_rp/runtime/production_wrapper.py,sha256=yD98TQZmhxbgPNocnjAtj9LA66EepbApBdTr_bdC5eU,8112
85
+ tetra_rp/runtime/reliability_config.py,sha256=gfUi6Rc5Vf0TSPQM6FKQtA1jvxxz6qth7zQvE8WEyXM,4733
86
+ tetra_rp/runtime/retry_manager.py,sha256=6vfvsSwvlzM5Tx-MA1Di9SzMtWQDV8IlPCb0J0Z2fR0,4252
87
+ tetra_rp/runtime/serialization.py,sha256=2TORWMkWcLd1UECLHm4OQM9p2Fswmqr8Jgd8LmSWtj4,3241
88
+ tetra_rp/runtime/service_registry.py,sha256=kH1fEz2sAUzEFhCHNs2YKfS-Bl5HQkGgBP-FV0x6zac,12302
89
+ tetra_rp/runtime/state_manager_client.py,sha256=6a-z8w1mSLcNePLSe9ujbWxffHDH0BR8llPWfPyLMGY,8935
90
+ tetra_rp/stubs/__init__.py,sha256=ozKsHs8q0T7o2qhQEquub9hqomh1Htys53mMraaRu2E,72
91
+ tetra_rp/stubs/live_serverless.py,sha256=ymHgXrq42O2RB-pG1JrsnFx6xW26TtdAVVUy3RH_nZ8,4622
92
+ tetra_rp/stubs/load_balancer_sls.py,sha256=-Q_6sR2THBeIAJecWWJ_tDMU6e5m1rJ2VxUoL6_GwFI,13423
93
+ tetra_rp/stubs/registry.py,sha256=fwBhFCf93ybYt3rK1YRYqdL6fxO8M6kdUOjrRC-nwcs,5855
94
+ tetra_rp/stubs/serverless.py,sha256=BM_a5Ml5VADBYu2WRNmo9qnicP8NnXDGl5ywifulbD0,947
95
+ tetra_rp-0.24.0.dist-info/METADATA,sha256=EpQ1U1-PNmZIRtaY3Ytl6WCy9KhefOTKPUpuVZvcxtw,43147
96
+ tetra_rp-0.24.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
97
+ tetra_rp-0.24.0.dist-info/entry_points.txt,sha256=FJi3ytBLKCcyz4tXJhOM3XNKzTxpnl3AauiPH2lHvWY,48
98
+ tetra_rp-0.24.0.dist-info/top_level.txt,sha256=bBay7JTDwJXsTYvVjrwno9hnF-j0q272lk65f2AcPjU,9
99
+ tetra_rp-0.24.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flash = tetra_rp.cli.main:app
@@ -1,177 +0,0 @@
1
- import time
2
- from worker import Worker
3
- from job import Job
4
-
5
- from dataclass import WorkerStatus, JobStatus
6
-
7
- import logging
8
- import inspect
9
-
10
-
11
- def setup_logging(level=logging.INFO, fmt=None):
12
- if fmt is None:
13
- fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
14
- logging.basicConfig(level=level, format=fmt)
15
-
16
-
17
- def get_logger(name=None):
18
- """
19
- Returns a logger. If no name is provided, it infers the caller's module name.
20
- """
21
- if name is None:
22
- # Get the caller's module name.
23
- frame = inspect.stack()[1]
24
- module = inspect.getmodule(frame[0])
25
- name = module.__name__ if module else "__main__"
26
- return logging.getLogger(name)
27
-
28
-
29
- logger = get_logger(__name__)
30
-
31
-
32
- class ClusterManager:
33
- """
34
- Manages workers and Jobs currently in Memory:
35
- - Runpod for provisioning
36
- - Real remote execution
37
- - Data base for the
38
- """
39
-
40
- def __init__(self):
41
- self.workers = {} # Worker ID -> Worker
42
- self.jobs = {} # Job ID -> Job
43
-
44
- # ----------------- Worker Management -----------------
45
- # ------------------------------------------------------
46
- def add_worker(self, resource_config: dict):
47
- """
48
- Add a new worker to the cluster
49
- """
50
- # here will go the logic to create a worker and add it to the cluster: RUNPOD LOGIC will be added here.
51
- worker = Worker(resource_config)
52
- self.workers[worker.worker_id] = worker
53
-
54
- logger.info(f"Added worker {worker.worker_id} to the cluster")
55
- return worker.worker_id
56
-
57
- def remove_worker(self, worker_id):
58
- """
59
- Remove a worker from the cluster
60
- """
61
- worker = self.workers.get(worker_id)
62
- if not worker:
63
- logger.error(f"Worker {worker_id} not found")
64
- return False
65
- if worker.status == WorkerStatus.RUNNING:
66
- logger.error(f"Worker {worker_id} is still running")
67
- return False
68
- del self.workers[worker_id]
69
- logger.info(f"Removed worker {worker_id} from the cluster")
70
- return True
71
-
72
- def list_workers(self):
73
- """
74
- List all workers in the cluster
75
- """
76
- return list(self.workers.values())
77
-
78
- # ----------------- Job Management -----------------
79
- # ---------------------------------------------------
80
-
81
- def submit_job(self, resource_config: dict):
82
- """
83
- Submit a new job to the cluster (Queueud). Then attempt to scheduel it.
84
- """
85
- job = Job(resource_config)
86
- self.jobs[job.job_id] = job
87
- logger.info(f"Submitted job {job.job_id} to the cluster")
88
- # attempt to schedule the job
89
- self.schedule_job(job)
90
- return job.job_id
91
-
92
- def schedule_job(self, job: Job):
93
- """
94
- find a suitable worker for the job. It none, Job remains queued.
95
- If we want to a auto provision we can actually add a logic here to add a worker if none is available.
96
- """
97
- if job.status != JobStatus.QUEUED:
98
- logger.error(f"Job {job.job_id} is not pending")
99
- return False
100
-
101
- # Find worker candidate
102
- candidate = self.find_idle_worker(job.resource_config)
103
- if candidate:
104
- self.assign_job_to_worker(job, candidate)
105
- else:
106
- logger.info(f"No worker available for job {job.job_id}")
107
- # we cn either provision new worker from here and then scehediule the job from here.
108
-
109
- def find_idle_worker(self, resource_config: dict):
110
- """
111
- Find an idle worker that can run the job
112
- """
113
- for w in self.workers.values():
114
- if w.status == WorkerStatus.IDLE:
115
- # check the resource config
116
- if w.resource_config == resource_config:
117
- continue
118
- return w
119
- return None
120
-
121
- def assign_job_to_worker(self, job: Job, worker: Worker):
122
- """
123
- Mark the job as running and the worker as Running and 'execute' the job.
124
- In a real system, we would send a remote command to the worker (eg: gRPC) to execute the job.
125
- """
126
- job.worker_id = worker.worker_id
127
- job.status = JobStatus.RUNNING
128
- worker.status = WorkerStatus.RUNNING
129
- worker.current_job_id = job.job_id
130
- logger.info(f"Assigned job {job.job_id} to worker {worker.worker_id}")
131
- self._execute_job(job, worker)
132
-
133
- def _execute_job(self, job: Job, worker: Worker):
134
- """
135
- Simulate the remote execution. right now, we jsut sleep for 1s.
136
- In production, what we we can do is:
137
- - Open a gRPC connection to the worker
138
- - pass the job details
139
- - wait for the compeltion call back
140
- """
141
- try:
142
- logger.info(f"Executing job {job.job_id} on worker {worker.worker_id}")
143
- time.sleep(
144
- 1
145
- ) # Here we can add the actual execution logic, currently it mimics the execution.
146
-
147
- # mark the job as completed
148
- job.status = JobStatus.COMPLETED
149
- job.result = "Job completed successfully"
150
- logger.info(f"[Cluster Manager] Job {job.job_id} completed successfully")
151
- except Exception as e:
152
- job.status = JobStatus.FAILED
153
- job.result = f"Job failed: {str(e)}"
154
- logger.error(f"[Cluster Manager] Job {job.job_id} failed: {str(e)}")
155
- finally:
156
- worker.status = WorkerStatus.IDLE
157
- worker.current_job_id = None
158
-
159
- def get_job_status(self, job_id):
160
- """
161
- Get the job details
162
- """
163
- job = self.jobs.get(job_id)
164
- if not job:
165
- logger.error(f"Job {job_id} not found")
166
- return None
167
- return job
168
-
169
- # this function has retry logic but it's currently fuzzy, we might have to change it.
170
-
171
- def retry_queued_jobs(self):
172
- """
173
- Retry all queued jobs
174
- """
175
- for job in self.jobs.values():
176
- if job.status == JobStatus.QUEUED:
177
- self.schedule_job(job)
@@ -1,18 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class WorkerStatus(Enum):
5
- """Enum representing the status of a worker"""
6
-
7
- IDLE = "idle"
8
- RUNNING = "running"
9
- OFFLINE = "offline"
10
-
11
-
12
- class JobStatus(Enum):
13
- """Enum representing the status of a job"""
14
-
15
- QUEUED = "queued"
16
- RUNNING = "running"
17
- COMPLETED = "completed"
18
- FAILED = "failed"
tetra_rp/core/pool/ex.py DELETED
@@ -1,38 +0,0 @@
1
- from cluster_manager import ClusterManager
2
-
3
-
4
- if __name__ == "__main__":
5
- cm = ClusterManager()
6
-
7
- # 1) Submit a job with no existing workers (use resource_config dict)
8
- job_id = cm.submit_job(
9
- resource_config={"gpu": "H100", "memory": 16, "network_volume": 50}
10
- )
11
- print(
12
- "Job status:", cm.get_job_status(job_id)
13
- ) # should be QUEUED, no suitable worker
14
-
15
- # 2) Add a worker that doesn't match the GPU
16
- w1 = cm.add_worker(
17
- resource_config={"gpu": "H100", "memory": 16, "network_volume": 50}
18
- )
19
- # Re-try scheduling
20
- cm.retry_queued_jobs()
21
- print("Job status (still queued):", cm.get_job_status(job_id))
22
-
23
- # 3) Add a matching worker
24
- w2 = cm.add_worker(
25
- resource_config={"gpu": "H100", "memory": 16, "network_volume": 50}
26
- )
27
- # Re-try scheduling
28
- cm.retry_queued_jobs()
29
- print("Job status (should complete):", cm.get_job_status(job_id))
30
-
31
- # 4) Submit another job that requires less resources
32
- job_id2 = cm.submit_job(resource_config={"memory": 8, "network_volume": 10})
33
- # Should be assigned to w1 if it's idle
34
- print("Job2 final status:", cm.get_job_status(job_id2))
35
-
36
- # 5) Show final state of workers
37
- for worker in cm.list_workers():
38
- print("Worker:", worker)
tetra_rp/core/pool/job.py DELETED
@@ -1,22 +0,0 @@
1
- import uuid
2
- from dataclass import JobStatus
3
-
4
-
5
- class Job:
6
- """Represents a 'job' in the system
7
-
8
- In a real system, this might contain the function to run,
9
- arguments, and reference to data or code.
10
- """
11
-
12
- def __init__(self, resource_config: dict):
13
- self.job_id = str(uuid.uuid4())[:8]
14
- self.resource_config = resource_config
15
- self.status = JobStatus.QUEUED
16
-
17
- self.worker_id = None
18
- self.result = None
19
- self.error = None
20
-
21
- def __repr__(self):
22
- return f"Job(job_id={self.job_id}, status={self.status})"
@@ -1,19 +0,0 @@
1
- import uuid
2
- from dataclass import WorkerStatus
3
-
4
-
5
- class Worker:
6
- """Represents a single worker in the pool
7
-
8
- For Now we store ressources in memory
9
- """
10
-
11
- def __init__(self, resource_config: dict):
12
- self.worker_id = str(uuid.uuid4())[:8]
13
- self.resource_config = resource_config
14
- self.status = WorkerStatus.IDLE
15
-
16
- self.current_job_id = None
17
-
18
- def __repr__(self):
19
- return f"Worker(worker_id={self.worker_id}, status={self.status})"
@@ -1,50 +0,0 @@
1
- from typing import Callable, Any, List, Union
2
- from pydantic import BaseModel
3
- from .gpu import GpuType, GpuTypeDetail
4
- from .serverless import ServerlessEndpoint
5
-
6
-
7
- """
8
- Define the mapping for the methods and their return types
9
- Only include methods from runpod.*
10
- """
11
- RUNPOD_TYPED_OPERATIONS = {
12
- "get_gpus": List[GpuType],
13
- "get_gpu": GpuTypeDetail,
14
- "get_endpoints": List[ServerlessEndpoint],
15
- }
16
-
17
-
18
- def inquire(method: Callable, *args, **kwargs) -> Union[List[Any], Any]:
19
- """
20
- This function dynamically determines the return type of the provided method
21
- based on a predefined mapping (`definitions`) and validates the result using
22
- Pydantic models if applicable.
23
-
24
- Refer to `RUNPOD_TYPED_OPERATIONS` for the mapping.
25
-
26
- Example:
27
- ----------
28
- >>> import runpod
29
- >>> inquire(runpod.get_gpus)
30
- [
31
- GpuType(id='NVIDIA A100 80GB', displayName='A100 80GB', memoryInGb=80),
32
- GpuType(id='NVIDIA A100 40GB', displayName='A100 40GB', memoryInGb=40),
33
- GpuType(id='NVIDIA A10', displayName='A10', memoryInGb=24)
34
- ]
35
- """
36
- method_name = method.__name__
37
- return_type = RUNPOD_TYPED_OPERATIONS.get(method_name)
38
-
39
- raw_result = method(*args, **kwargs)
40
-
41
- if hasattr(return_type, "__origin__") and return_type.__origin__ is list:
42
- # List case
43
- model_type = return_type.__args__[0]
44
- if issubclass(model_type, BaseModel):
45
- return [model_type.model_validate(item) for item in raw_result]
46
- elif isinstance(return_type, type) and issubclass(return_type, BaseModel):
47
- # Single object case
48
- return return_type.model_validate(raw_result)
49
- else:
50
- raise ValueError(f"Unsupported return type for method '{method_name}'")
@@ -1,33 +0,0 @@
1
- from enum import Enum
2
- from typing import Any
3
- from pydantic import BaseModel
4
-
5
-
6
- def normalize_for_json(obj: Any) -> Any:
7
- """
8
- Recursively normalizes an object for JSON serialization.
9
-
10
- This function handles various data types and ensures that objects
11
- are converted into JSON-serializable formats. It supports the following:
12
- - `BaseModel` instances: Converts them to dictionaries using `model_dump()`.
13
- - Dictionaries: Recursively normalizes their values.
14
- - Lists: Recursively normalizes their elements.
15
- - Tuples: Recursively normalizes their elements and returns a tuple.
16
- - Other types: Returns the object as is.
17
-
18
- Args:
19
- obj (Any): The object to normalize.
20
-
21
- Returns:
22
- Any: A JSON-serializable representation of the input object.
23
- """
24
- if isinstance(obj, BaseModel):
25
- return normalize_for_json(obj.model_dump())
26
- elif isinstance(obj, Enum):
27
- return obj.value
28
- elif isinstance(obj, dict):
29
- return {k: normalize_for_json(v) for k, v in obj.items()}
30
- elif isinstance(obj, (list, tuple)):
31
- return type(obj)(normalize_for_json(i) for i in obj)
32
- else:
33
- return obj
@@ -1,39 +0,0 @@
1
- tetra_rp/__init__.py,sha256=-1S5sYIKtnUV8V1HlSIbX1yZwiUrsO8J5b3ZEIR_phU,687
2
- tetra_rp/client.py,sha256=sJk3kneFJo40OAtbxucbaJ6NxMs-kD2jkpXYwG0vJhM,2681
3
- tetra_rp/logger.py,sha256=gk5-PWp3k_GQ5DxndsRkBCX0jarp_3lgZ1oiTFuThQg,1125
4
- tetra_rp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- tetra_rp/core/api/__init__.py,sha256=oldrEKMwxYoBPLvPfVlaFS3wfUtTTxCN6-HzlpTh6vE,124
6
- tetra_rp/core/api/runpod.py,sha256=n1pfvzDceU_yO9iOn4B9Kst6YL2KD0m-migm3bvnfJM,10374
7
- tetra_rp/core/pool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- tetra_rp/core/pool/cluster_manager.py,sha256=KJxEp_044HjnbOhfIdiXZbks_bFDYE1KgKeR5W9VvbY,6007
9
- tetra_rp/core/pool/dataclass.py,sha256=YngS328_NTewY8Etitj4k7MmdM5GWqqE_OMbytrVNlw,338
10
- tetra_rp/core/pool/ex.py,sha256=AZOrn9t_X5ycMl-tDg7-jcIURj_9kVmzn9_da8h1TFI,1273
11
- tetra_rp/core/pool/job.py,sha256=4bisW_ZwiQ2-qD5l0y9SbHcO4EQvSKimmBBU1fpI_YE,567
12
- tetra_rp/core/pool/worker.py,sha256=N4cOnf8MiDcPFH2XSMmSnnWMACZYUNnKWVhOx2aSxvM,478
13
- tetra_rp/core/resources/__init__.py,sha256=UhIwo1Y6-tw5qsULamR296sQiztuz-oWrSTreqfmFSw,814
14
- tetra_rp/core/resources/base.py,sha256=UJeDiFN45aO1n5SBcxn56ohLhj-AWHoj0KO7mF4yJ_o,1440
15
- tetra_rp/core/resources/cloud.py,sha256=XJOWPfzYlDVJGHxgffcfpEaOKrWhGdi7AzTlaGuYj0o,70
16
- tetra_rp/core/resources/constants.py,sha256=F1gPqFaXcCmfrbUSO9PQtUBv984TxFc3pySgVy-kXk8,158
17
- tetra_rp/core/resources/cpu.py,sha256=YIE-tKolSU3JJzpPB7ey-PbRdqKWsJZ_Ad4h2OYaaiA,1231
18
- tetra_rp/core/resources/environment.py,sha256=FC9kJCa8YLSar75AKUKqJYnNLrUdjZj8ZTOrspBrS00,1267
19
- tetra_rp/core/resources/gpu.py,sha256=2jIIMr8PNnlIAP8ZTKO8Imx-rdxXp2rbdSHJeVfjawk,1858
20
- tetra_rp/core/resources/live_serverless.py,sha256=6r4I4TEx9AmZ0-OJvE86qrY0S7BEx9t_P2zwHVdtbew,1074
21
- tetra_rp/core/resources/network_volume.py,sha256=mzYA7Bf4JTFiDyH0sLrUbPjq-26MWgbbRWAMbX2h6iA,2881
22
- tetra_rp/core/resources/resource_manager.py,sha256=kUVZDblfUzaG78S8FwOzu4rN6QSegUgQNK3fJ_X7l0w,2834
23
- tetra_rp/core/resources/serverless.py,sha256=lZMITI1cwOBVNX3dbFyR01AeRZ0eatNC4CRE7vwUrqs,14726
24
- tetra_rp/core/resources/template.py,sha256=UkflJXZFWIbQkLuUt4oRLAjn-yIpw9_mT2X1cAH69CU,3141
25
- tetra_rp/core/resources/utils.py,sha256=mgXfgz_NuHN_IC7TzMNdH9II-LMjxcDCG7syDTcPiGs,1721
26
- tetra_rp/core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- tetra_rp/core/utils/backoff.py,sha256=1pfa0smFNpib8nztcIgBbtrVvQeECKh-aNOfL2TztgU,1324
28
- tetra_rp/core/utils/json.py,sha256=q0r7aEdfh8kKVeHGeh9fBDfuhHYNopSreislAMB6HhM,1163
29
- tetra_rp/core/utils/singleton.py,sha256=JRli0HhBfq4P9mBUOg1TZUUwMvIenRqWdymX3qFMm2k,210
30
- tetra_rp/protos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- tetra_rp/protos/remote_execution.py,sha256=I4641-Dlzj4O7AuZbVei8O9aV2VNrRTcE8r7Fm0e-V8,1901
32
- tetra_rp/stubs/__init__.py,sha256=ozKsHs8q0T7o2qhQEquub9hqomh1Htys53mMraaRu2E,72
33
- tetra_rp/stubs/live_serverless.py,sha256=o1NH5XEwUD-27NXJsEGO0IwnuDp8iXwUiw5nZtaZZOI,4199
34
- tetra_rp/stubs/registry.py,sha256=V4m3CeXl8j1pguHuuflxqpWeBgVDQ93YkhxJbElyP7Q,2599
35
- tetra_rp/stubs/serverless.py,sha256=BM_a5Ml5VADBYu2WRNmo9qnicP8NnXDGl5ywifulbD0,947
36
- tetra_rp-0.6.0.dist-info/METADATA,sha256=CPOdAGUy5vZOSLazBQubYChiQkuwDldW3G0K9KsyBlw,28055
37
- tetra_rp-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
38
- tetra_rp-0.6.0.dist-info/top_level.txt,sha256=bBay7JTDwJXsTYvVjrwno9hnF-j0q272lk65f2AcPjU,9
39
- tetra_rp-0.6.0.dist-info/RECORD,,
File without changes