11import json
2- from typing import Dict , List , Optional
2+ from pathlib import Path
3+ from time import time
4+ from typing import Dict , List , Optional , BinaryIO , Union
5+
6+ import requests .exceptions
37
48from brainframe .api .bf_codecs import Capsule
5- from .base_stub import BaseStub , DEFAULT_TIMEOUT
9+ from .base_stub import DEFAULT_TIMEOUT
10+ from .storage import StorageStubMixin
611
712
8- class CapsuleStubMixin (BaseStub ):
13+ class CapsuleStubMixin (StorageStubMixin ):
914 """Provides stubs to call APIs to inspect and configure capsules."""
1015
1116 def get_capsule (self , name ,
@@ -28,6 +33,61 @@ def get_capsules(self, timeout=DEFAULT_TIMEOUT) -> List[Capsule]:
2833 capsules , _ = self ._get_json (req , timeout )
2934 return [Capsule .from_dict (d ) for d in capsules ]
3035
36+ def load_capsule (self , storage_id : int ,
37+ source_path : Optional [Path ] = None ,
38+ timeout : float = DEFAULT_TIMEOUT ) -> Capsule :
39+ """Loads and initializes a capsule from capsule data in storage.
40+
41+ :param storage_id: The ID of the raw capsule data in storage
42+ :param source_path: If available, the path to the source code on the
43+ development machine can be provided. Doing so allows stack traces
44+ to point to the correct source location.
45+ :param timeout: The timeout to use for this request
46+ :return: The loaded capsule
47+ """
48+ req = f"/api/plugins"
49+ req_object = {
50+ "storage_id" : storage_id ,
51+ "dev_options" : {
52+ "source_path" : str (source_path ),
53+ },
54+ }
55+ capsule = self ._put_json (req , timeout , json .dumps (req_object ))
56+ return Capsule .from_dict (capsule )
57+
58+ def upload_and_load_capsule (self , data : Union [bytes , BinaryIO ],
59+ source_path : Optional [Path ] = None ,
60+ timeout : float = DEFAULT_TIMEOUT ) -> Capsule :
61+ """Uploads capsule data to storage, then loads and initializes a
62+ capsule from it. This is a utility method that combines the
63+ functionality of `new_storage` and `load_capsule`.
64+
65+ :param data: The data to store, either as bytes or as a file-like
66+ :param source_path: If available, the path to the source code on the
67+ development machine can be provided. Doing so allows stack traces
68+ to point to the correct source location.
69+ :param timeout: The timeout to use for each request
70+ :return: The loaded capsule
71+ """
72+ storage_id = self .new_storage (data ,
73+ mime_type = "application/octet-stream" ,
74+ timeout = timeout )
75+
76+ return self .load_capsule (storage_id ,
77+ source_path ,
78+ timeout = timeout )
79+
80+ def unload_capsule (self , capsule_name : str ,
81+ timeout : float = DEFAULT_TIMEOUT ) -> None :
82+ """Unloads a capsule and deletes its data from storage. This method may
83+ only be used with capsules that were loaded through the REST API.
84+
85+ :param capsule_name: The name of the capsule to unload
86+ :param timeout: The timeout to use for this request
87+ """
88+ req = f"/api/plugins/{ capsule_name } "
89+ self ._delete (req , timeout )
90+
3191 def get_capsule_option_vals (self , capsule_name , stream_id = None ,
3292 timeout = DEFAULT_TIMEOUT ) \
3393 -> Dict [str , object ]:
0 commit comments