cycls 0.0.2.93__tar.gz → 0.0.2.94__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cycls
3
- Version: 0.0.2.93
3
+ Version: 0.0.2.94
4
4
  Summary: Distribute Intelligence
5
5
  Author-email: "Mohammed J. AlRujayi" <mj@cycls.com>
6
6
  Requires-Python: >=3.10
@@ -79,6 +79,13 @@ class App(Function):
79
79
  self._prepare_func(prod=True)
80
80
  return super().deploy(port=port)
81
81
 
82
+ def _deploy(self, port=8080):
83
+ """Deploy to testing infrastructure."""
84
+ if self.api_key is None:
85
+ raise RuntimeError("Missing API key. Set cycls.api_key or CYCLS_API_KEY environment variable.")
86
+ self._prepare_func(prod=True)
87
+ return super()._deploy(port=port)
88
+
82
89
 
83
90
  def app(name=None, **kwargs):
84
91
  """Decorator that transforms a function into a deployable App."""
@@ -396,6 +396,50 @@ CMD ["python", "entrypoint.py"]
396
396
  print(f"Connection error: {e}")
397
397
  return None
398
398
 
399
+ def _deploy(self, *args, **kwargs):
400
+ import requests
401
+
402
+ port = kwargs.pop('port', 8080)
403
+ print(f"Deploying '{self.name}'...")
404
+
405
+ payload = cloudpickle.dumps((self.func, args, {**kwargs, 'port': port}))
406
+ archive_name = f"{self.name}-{hashlib.sha256(payload).hexdigest()[:16]}.tar.gz"
407
+
408
+ with tempfile.TemporaryDirectory() as tmpdir:
409
+ workdir = Path(tmpdir)
410
+ self._prepare_deploy_context(workdir, port, args, kwargs)
411
+
412
+ archive_path = workdir / archive_name
413
+ with tarfile.open(archive_path, "w:gz") as tar:
414
+ for f in workdir.glob("**/*"):
415
+ if f.is_file() and f != archive_path:
416
+ tar.add(f, arcname=f.relative_to(workdir))
417
+
418
+ print("Uploading...")
419
+ with open(archive_path, 'rb') as f:
420
+ response = requests.post(
421
+ "https://api-572247013948.me-central1.run.app/v1/deploy",
422
+ data={"function_name": self.name, "port": port},
423
+ files={'source_archive': (archive_name, f, 'application/gzip')},
424
+ headers={"X-API-Key": self.api_key},
425
+ timeout=9000,
426
+ stream=True,
427
+ )
428
+
429
+ # Parse NDJSON stream
430
+ url = None
431
+ for line in response.iter_lines(decode_unicode=True):
432
+ if line:
433
+ event = json.loads(line)
434
+ status = event.get("status", "")
435
+ msg = event.get("message", "")
436
+ print(f" [{status}] {msg}")
437
+ if status == "DONE":
438
+ url = event.get("url")
439
+ elif status == "ERROR":
440
+ return None
441
+ return url
442
+
399
443
  def __del__(self):
400
444
  self._cleanup_container()
401
445