nebu 0.1.61__py3-none-any.whl → 0.1.63__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.
- nebu/config.py +14 -0
- nebu/namespaces/models.py +20 -0
- nebu/namespaces/namespace.py +155 -0
- nebu/processors/decorate.py +2 -5
- {nebu-0.1.61.dist-info → nebu-0.1.63.dist-info}/METADATA +1 -1
- {nebu-0.1.61.dist-info → nebu-0.1.63.dist-info}/RECORD +9 -7
- {nebu-0.1.61.dist-info → nebu-0.1.63.dist-info}/WHEEL +0 -0
- {nebu-0.1.61.dist-info → nebu-0.1.63.dist-info}/licenses/LICENSE +0 -0
- {nebu-0.1.61.dist-info → nebu-0.1.63.dist-info}/top_level.txt +0 -0
nebu/config.py
CHANGED
@@ -134,6 +134,20 @@ class GlobalConfig:
|
|
134
134
|
return srv
|
135
135
|
return None
|
136
136
|
|
137
|
+
@classmethod
|
138
|
+
def get_server_url(cls) -> str:
|
139
|
+
"""
|
140
|
+
Get the server URL for the current_server name, or None if unset/missing.
|
141
|
+
"""
|
142
|
+
config = cls.read()
|
143
|
+
server_config = config.get_current_server_config()
|
144
|
+
server = os.environ.get("NEBU_SERVER") or os.environ.get("NEBULOUS_SERVER")
|
145
|
+
if not server:
|
146
|
+
server = server_config.server if server_config else None
|
147
|
+
if not server:
|
148
|
+
raise ValueError("NEBULOUS_SERVER environment variable is not set")
|
149
|
+
return server
|
150
|
+
|
137
151
|
|
138
152
|
def _get_config_file_path() -> str:
|
139
153
|
"""
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from typing import Dict, Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
from nebu.meta import V1ResourceMeta
|
6
|
+
|
7
|
+
|
8
|
+
class V1NamespaceMetaRequest(BaseModel):
|
9
|
+
name: str
|
10
|
+
labels: Optional[Dict[str, str]] = None
|
11
|
+
owner: Optional[str] = None
|
12
|
+
|
13
|
+
|
14
|
+
class V1NamespaceRequest(BaseModel):
|
15
|
+
metadata: V1NamespaceMetaRequest
|
16
|
+
|
17
|
+
|
18
|
+
class V1Namespace(BaseModel):
|
19
|
+
kind: str = Field(default="Namespace")
|
20
|
+
metadata: V1ResourceMeta
|
@@ -0,0 +1,155 @@
|
|
1
|
+
from typing import Dict, List, Optional
|
2
|
+
|
3
|
+
import requests
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
6
|
+
from nebu.config import GlobalConfig
|
7
|
+
from nebu.namespaces.models import (
|
8
|
+
V1Namespace,
|
9
|
+
V1NamespaceMetaRequest,
|
10
|
+
V1NamespaceRequest,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
class V1Namespaces(BaseModel):
|
15
|
+
namespaces: List[V1Namespace]
|
16
|
+
|
17
|
+
|
18
|
+
class Namespace:
|
19
|
+
"""
|
20
|
+
A class for managing Namespace instances.
|
21
|
+
"""
|
22
|
+
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
name: str,
|
26
|
+
labels: Optional[Dict[str, str]] = None,
|
27
|
+
owner: Optional[str] = None,
|
28
|
+
config: Optional[GlobalConfig] = None,
|
29
|
+
):
|
30
|
+
self.config = config or GlobalConfig.read()
|
31
|
+
if not self.config:
|
32
|
+
raise ValueError("No config found")
|
33
|
+
current_server = self.config.get_current_server_config()
|
34
|
+
if not current_server:
|
35
|
+
raise ValueError("No server config found")
|
36
|
+
self.current_server = current_server
|
37
|
+
self.api_key = current_server.api_key
|
38
|
+
self.nebu_host = current_server.server
|
39
|
+
self.name = name
|
40
|
+
self.labels = labels
|
41
|
+
self.owner = owner
|
42
|
+
self.namespaces_url = f"{self.nebu_host}/v1/namespaces"
|
43
|
+
|
44
|
+
# Fetch existing Namespaces
|
45
|
+
response = requests.get(
|
46
|
+
self.namespaces_url, headers={"Authorization": f"Bearer {self.api_key}"}
|
47
|
+
)
|
48
|
+
response.raise_for_status()
|
49
|
+
|
50
|
+
existing_namespaces = V1Namespaces.model_validate(response.json())
|
51
|
+
self.namespace: Optional[V1Namespace] = next(
|
52
|
+
(
|
53
|
+
namespace_val
|
54
|
+
for namespace_val in existing_namespaces.namespaces
|
55
|
+
if namespace_val.metadata.name == name
|
56
|
+
),
|
57
|
+
None,
|
58
|
+
)
|
59
|
+
|
60
|
+
# If not found, create
|
61
|
+
if not self.namespace:
|
62
|
+
print(f"Creating namespace {name}")
|
63
|
+
# Create metadata and namespace request
|
64
|
+
metadata = V1NamespaceMetaRequest(name=name, labels=labels, owner=owner)
|
65
|
+
|
66
|
+
namespace_request = V1NamespaceRequest(
|
67
|
+
metadata=metadata,
|
68
|
+
)
|
69
|
+
|
70
|
+
create_response = requests.post(
|
71
|
+
self.namespaces_url,
|
72
|
+
json=namespace_request.model_dump(exclude_none=True),
|
73
|
+
headers={"Authorization": f"Bearer {self.api_key}"},
|
74
|
+
)
|
75
|
+
create_response.raise_for_status()
|
76
|
+
self.namespace = V1Namespace.model_validate(create_response.json())
|
77
|
+
print(f"Created Namespace {self.namespace.metadata.name}")
|
78
|
+
else:
|
79
|
+
print(f"Found Namespace {self.namespace.metadata.name}, no update needed")
|
80
|
+
|
81
|
+
@classmethod
|
82
|
+
def load(
|
83
|
+
cls,
|
84
|
+
name: str,
|
85
|
+
config: Optional[GlobalConfig] = None,
|
86
|
+
):
|
87
|
+
"""
|
88
|
+
Get a Namespace from the remote server.
|
89
|
+
"""
|
90
|
+
namespaces = cls.get(name=name, config=config)
|
91
|
+
if not namespaces:
|
92
|
+
raise ValueError("Namespace not found")
|
93
|
+
namespace_v1 = namespaces[0]
|
94
|
+
|
95
|
+
out = cls.__new__(cls)
|
96
|
+
out.namespace = namespace_v1
|
97
|
+
out.config = config or GlobalConfig.read()
|
98
|
+
if not out.config:
|
99
|
+
raise ValueError("No config found")
|
100
|
+
out.current_server = out.config.get_current_server_config()
|
101
|
+
if not out.current_server:
|
102
|
+
raise ValueError("No server config found")
|
103
|
+
out.api_key = out.current_server.api_key
|
104
|
+
out.nebu_host = out.current_server.server
|
105
|
+
out.namespaces_url = f"{out.nebu_host}/v1/namespaces"
|
106
|
+
out.name = name
|
107
|
+
|
108
|
+
return out
|
109
|
+
|
110
|
+
@classmethod
|
111
|
+
def get(
|
112
|
+
cls,
|
113
|
+
name: Optional[str] = None,
|
114
|
+
config: Optional[GlobalConfig] = None,
|
115
|
+
) -> List[V1Namespace]:
|
116
|
+
"""
|
117
|
+
Get a list of Namespaces that optionally match the name filter.
|
118
|
+
"""
|
119
|
+
config = config or GlobalConfig.read()
|
120
|
+
if not config:
|
121
|
+
raise ValueError("No config found")
|
122
|
+
current_server = config.get_current_server_config()
|
123
|
+
if not current_server:
|
124
|
+
raise ValueError("No server config found")
|
125
|
+
namespaces_url = f"{current_server.server}/v1/namespaces"
|
126
|
+
|
127
|
+
response = requests.get(
|
128
|
+
namespaces_url,
|
129
|
+
headers={"Authorization": f"Bearer {current_server.api_key}"},
|
130
|
+
)
|
131
|
+
response.raise_for_status()
|
132
|
+
|
133
|
+
namespaces_response = V1Namespaces.model_validate(response.json())
|
134
|
+
filtered_namespaces = namespaces_response.namespaces
|
135
|
+
|
136
|
+
if name:
|
137
|
+
filtered_namespaces = [
|
138
|
+
n for n in filtered_namespaces if n.metadata.name == name
|
139
|
+
]
|
140
|
+
|
141
|
+
return filtered_namespaces
|
142
|
+
|
143
|
+
def delete(self):
|
144
|
+
"""
|
145
|
+
Delete the Namespace.
|
146
|
+
"""
|
147
|
+
if not self.namespace or not self.namespace.metadata.name:
|
148
|
+
raise ValueError("Namespace not found")
|
149
|
+
|
150
|
+
url = f"{self.namespaces_url}/{self.namespace.metadata.name}"
|
151
|
+
response = requests.delete(
|
152
|
+
url, headers={"Authorization": f"Bearer {self.api_key}"}
|
153
|
+
)
|
154
|
+
response.raise_for_status()
|
155
|
+
return
|
nebu/processors/decorate.py
CHANGED
@@ -57,9 +57,7 @@ _NEBU_INSIDE_CONSUMER_ENV_VAR = "_NEBU_INSIDE_CONSUMER_EXEC"
|
|
57
57
|
CONTAINER_CODE_DIR = "/app/src"
|
58
58
|
# Define S3 prefix for code storage (under the base URI from token endpoint)
|
59
59
|
S3_CODE_PREFIX = "nebu-code"
|
60
|
-
|
61
|
-
# Use environment variable for flexibility, provide a default for local dev
|
62
|
-
NEBU_API_BASE_URL = os.environ.get("NEBU_API_BASE_URL", "http://localhost:3000")
|
60
|
+
NEBU_API_BASE_URL = GlobalConfig.get_server_url()
|
63
61
|
|
64
62
|
# --- Jupyter Helper Functions ---
|
65
63
|
|
@@ -69,7 +67,6 @@ def is_jupyter_notebook():
|
|
69
67
|
Determine if the current code is running inside a Jupyter notebook.
|
70
68
|
Returns bool: True if running inside a Jupyter notebook, False otherwise.
|
71
69
|
"""
|
72
|
-
# print("[DEBUG Helper] Checking if running in Jupyter...") # Reduce verbosity
|
73
70
|
try:
|
74
71
|
# Use importlib to avoid runtime dependency if not needed
|
75
72
|
import importlib.util
|
@@ -1078,7 +1075,7 @@ def processor(
|
|
1078
1075
|
# Setup commands: Base dependencies needed by consumer.py itself or the framework
|
1079
1076
|
# Install required dependencies for the consumer to run properly
|
1080
1077
|
base_deps_install = (
|
1081
|
-
"pip install
|
1078
|
+
"pip install orign redis PySocks pydantic dill boto3 requests"
|
1082
1079
|
)
|
1083
1080
|
setup_commands_list = [base_deps_install]
|
1084
1081
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
nebu/__init__.py,sha256=gJ49VnAs4GC_bUV90j-SS-iiYWESuCf4uuE7mx4T78k,385
|
2
2
|
nebu/auth.py,sha256=N_v6SPFD9HU_UoRDTaouH03g2Hmo9C-xxqInE1FweXE,1471
|
3
3
|
nebu/cache.py,sha256=jmluqvWnE9N8uNq6nppXSxEJK7DKWaB79GicaGg9KmY,4718
|
4
|
-
nebu/config.py,sha256=
|
4
|
+
nebu/config.py,sha256=C5Jt9Bd0i0HrgzBSVNJ-Ml3KwX_gaYbYYZEtNL2gvJg,7031
|
5
5
|
nebu/data.py,sha256=X0aAJYuHNVcTCRHpIDDm546HwMqIZpv40lGrozlL41A,39797
|
6
6
|
nebu/meta.py,sha256=CzFHMND9seuewzq9zNNx9WTr6JvrCBExe7BLqDSr7lM,745
|
7
7
|
nebu/builders/builder.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -10,16 +10,18 @@ nebu/containers/container.py,sha256=yb7KaPTVXnEEAlrpdlUi4HNqF6P7z9bmwAILGlq6iqU,
|
|
10
10
|
nebu/containers/decorator.py,sha256=uFtzlAXRHYZECJ-NPusY7oN9GXvdHrHDd_JNrIGr8aQ,3244
|
11
11
|
nebu/containers/models.py,sha256=0j6NGy4yto-enRDh_4JH_ZTbHrLdSpuMOqNQPnIrwC4,6815
|
12
12
|
nebu/containers/server.py,sha256=yFa2Y9PzBn59E1HftKiv0iapPonli2rbGAiU6r-wwe0,2513
|
13
|
+
nebu/namespaces/models.py,sha256=BPGWPLIIvY-PnOj6dVemxrx5Gr1PkchcXzjT0peRWLU,424
|
14
|
+
nebu/namespaces/namespace.py,sha256=Rjp1NW8a8Lq9jBXOQ91GPRjFdTGIftvMxl5x1fuH2iw,4993
|
13
15
|
nebu/processors/consumer.py,sha256=q4cFKPEfMf1xIs0Y3CjUDCR35QVjr0F_hSOZUKUYc_U,33667
|
14
|
-
nebu/processors/decorate.py,sha256=
|
16
|
+
nebu/processors/decorate.py,sha256=rzasgz_kq6yQosoABawu5yhkBj7i12Ah9ntBIVxEyrk,52928
|
15
17
|
nebu/processors/default.py,sha256=W4slJenG59rvyTlJ7gRp58eFfXcNOTT2Hfi6zzJAobI,365
|
16
18
|
nebu/processors/models.py,sha256=y40HoW-MEzDWB2dm_tsYlUy3Nf3s6eiLC0iGO9BoNog,3956
|
17
19
|
nebu/processors/processor.py,sha256=PsLs-Oo0bcvqoDKHErpOaic25y8uvTQ8KxtyFwLptW0,16165
|
18
20
|
nebu/processors/remote.py,sha256=TeAIPGEMqnDIb7H1iett26IEZrBlcbPB_-DSm6jcH1E,1285
|
19
21
|
nebu/redis/models.py,sha256=coPovAcVXnOU1Xh_fpJL4PO3QctgK9nBe5QYoqEcnxg,1230
|
20
22
|
nebu/services/service.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
|
-
nebu-0.1.
|
22
|
-
nebu-0.1.
|
23
|
-
nebu-0.1.
|
24
|
-
nebu-0.1.
|
25
|
-
nebu-0.1.
|
23
|
+
nebu-0.1.63.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
24
|
+
nebu-0.1.63.dist-info/METADATA,sha256=3881Gph2LZeest_4OHjONMujbr8MEtyOkmGOwVQJLqw,1731
|
25
|
+
nebu-0.1.63.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
26
|
+
nebu-0.1.63.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
|
27
|
+
nebu-0.1.63.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|