Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
dynamo
Commits
602352ce
Commit
602352ce
authored
Mar 08, 2025
by
Neelay Shah
Committed by
GitHub
Mar 08, 2025
Browse files
chore: rename dynamo (#44)
Co-authored-by:
Biswa Panda
<
biswa.panda@gmail.com
>
parent
ecf53ce2
Changes
431
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
178 additions
and
354 deletions
+178
-354
deploy/dynamo/operator/test/utils/utils.go
deploy/dynamo/operator/test/utils/utils.go
+0
-0
deploy/dynamo/sdk/README.md
deploy/dynamo/sdk/README.md
+0
-0
deploy/dynamo/sdk/pyproject.toml
deploy/dynamo/sdk/pyproject.toml
+8
-8
deploy/dynamo/sdk/src/dynamo/sdk/__init__.py
deploy/dynamo/sdk/src/dynamo/sdk/__init__.py
+8
-8
deploy/dynamo/sdk/src/dynamo/sdk/cli/cli.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/cli.py
+2
-2
deploy/dynamo/sdk/src/dynamo/sdk/cli/serve.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/serve.py
+1
-1
deploy/dynamo/sdk/src/dynamo/sdk/cli/serve_dynamo.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/serve_dynamo.py
+26
-26
deploy/dynamo/sdk/src/dynamo/sdk/cli/serving.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/serving.py
+22
-22
deploy/dynamo/sdk/src/dynamo/sdk/cli/start.py
deploy/dynamo/sdk/src/dynamo/sdk/cli/start.py
+1
-1
deploy/dynamo/sdk/src/dynamo/sdk/lib/__init__.py
deploy/dynamo/sdk/src/dynamo/sdk/lib/__init__.py
+0
-0
deploy/dynamo/sdk/src/dynamo/sdk/lib/decorators.py
deploy/dynamo/sdk/src/dynamo/sdk/lib/decorators.py
+12
-12
deploy/dynamo/sdk/src/dynamo/sdk/lib/dependency.py
deploy/dynamo/sdk/src/dynamo/sdk/lib/dependency.py
+41
-39
deploy/dynamo/sdk/src/dynamo/sdk/lib/image.py
deploy/dynamo/sdk/src/dynamo/sdk/lib/image.py
+3
-3
deploy/dynamo/sdk/src/dynamo/sdk/lib/service.py
deploy/dynamo/sdk/src/dynamo/sdk/lib/service.py
+53
-53
deploy/dynamo/sdk/uv.lock
deploy/dynamo/sdk/uv.lock
+1
-1
deploy/dynemo/api-server/.air.toml
deploy/dynemo/api-server/.air.toml
+0
-66
deploy/dynemo/api-server/.env
deploy/dynemo/api-server/.env
+0
-14
deploy/dynemo/api-server/.gitignore
deploy/dynemo/api-server/.gitignore
+0
-14
deploy/dynemo/api-server/Dockerfile
deploy/dynemo/api-server/Dockerfile
+0
-49
deploy/dynemo/api-server/Earthfile
deploy/dynemo/api-server/Earthfile
+0
-35
No files found.
deploy/dyn
e
mo/operator/test/utils/utils.go
→
deploy/dyn
a
mo/operator/test/utils/utils.go
View file @
602352ce
File moved
deploy/dyn
e
mo/sdk/README.md
→
deploy/dyn
a
mo/sdk/README.md
View file @
602352ce
File moved
deploy/dyn
e
mo/sdk/pyproject.toml
→
deploy/dyn
a
mo/sdk/pyproject.toml
View file @
602352ce
...
...
@@ -14,31 +14,31 @@
# limitations under the License.
[project]
name
=
"dyn
e
mo-sdk"
name
=
"dyn
a
mo-sdk"
version
=
"0.1.0"
description
=
"Distributed Inference Framework - SDK"
readme
=
"README.md"
authors
=
[
{
name
=
"NVIDIA Inc."
,
email
=
"sw-dl-dyn
e
mo@nvidia.com"
}
,
{
name
=
"NVIDIA Inc."
,
email
=
"sw-dl-dyn
a
mo@nvidia.com"
}
,
]
dependencies
=
[
# TODO: currently compatible with bentoml==1.4.1,
# v1.4.2 has removed normalize_identifier which is used in
compoundai
# "dyn
e
mo=={dyn
e
mo_version}",
# v1.4.2 has removed normalize_identifier which is used in
dynamo
# "dyn
a
mo=={dyn
a
mo_version}",
"bentoml==1.4.1"
,
"types-psutil==7.0.0.20250218"
,
]
[project.scripts]
dyn
e
mo-sdk
=
"dyn
e
mo.sdk.cli.cli:cli"
dyn
a
mo-sdk
=
"dyn
a
mo.sdk.cli.cli:cli"
[tool.setuptools]
namespace-packages
=
["dyn
e
mo"]
package-dir
=
{
"dyn
e
mo.sdk"
=
"src/dyn
e
mo/sdk"
}
namespace-packages
=
["dyn
a
mo"]
package-dir
=
{
"dyn
a
mo.sdk"
=
"src/dyn
a
mo/sdk"
}
[build-system]
requires
=
["hatchling"]
build-backend
=
"hatchling.build"
[tool.hatch.build.targets.wheel]
packages
=
["src/dynemo"]
\ No newline at end of file
packages
=
["src/dynamo"]
\ No newline at end of file
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/__init__.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/__init__.py
View file @
602352ce
...
...
@@ -18,21 +18,21 @@ from typing import Any
from
bentoml
import
api
# type: ignore
from
bentoml._internal.context
import
server_context
# type: ignore
from
dyn
e
mo.sdk.lib.decorators
import
async_onstart
,
dyn
e
mo_api
,
dyn
e
mo_endpoint
from
dyn
e
mo.sdk.lib.dependency
import
depends
from
dyn
e
mo.sdk.lib.image
import
DYNEMO_IMAGE
from
dyn
e
mo.sdk.lib.service
import
service
from
dyn
a
mo.sdk.lib.decorators
import
async_onstart
,
dyn
a
mo_api
,
dyn
a
mo_endpoint
from
dyn
a
mo.sdk.lib.dependency
import
depends
from
dyn
a
mo.sdk.lib.image
import
DYNEMO_IMAGE
from
dyn
a
mo.sdk.lib.service
import
service
dyn
e
mo_context
:
dict
[
str
,
Any
]
=
{}
dyn
a
mo_context
:
dict
[
str
,
Any
]
=
{}
__all__
=
[
"api"
,
"server_context"
,
"async_onstart"
,
"dyn
e
mo_api"
,
"dyn
e
mo_endpoint"
,
"dyn
a
mo_api"
,
"dyn
a
mo_endpoint"
,
"depends"
,
"DYNEMO_IMAGE"
,
"service"
,
"dyn
e
mo_context"
,
"dyn
a
mo_context"
,
]
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/cli/cli.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/cli/cli.py
View file @
602352ce
...
...
@@ -35,8 +35,8 @@ def create_bentoml_cli() -> click.Command:
from
bentoml_cli.secret
import
secret_command
from
bentoml_cli.utils
import
BentoMLCommandGroup
,
get_entry_points
from
dyn
e
mo.sdk.cli.serve
import
serve_command
from
dyn
e
mo.sdk.cli.start
import
start_command
from
dyn
a
mo.sdk.cli.serve
import
serve_command
from
dyn
a
mo.sdk.cli.start
import
start_command
server_context
.
service_type
=
"cli"
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/cli/serve.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/cli/serve.py
View file @
602352ce
...
...
@@ -318,7 +318,7 @@ def build_serve_command() -> click.Group:
else
:
# bentoml>=1.2
# from _bentoml_impl.server import serve_http
from
dyn
e
mo.sdk.cli.serving
import
serve_http
# type: ignore
from
dyn
a
mo.sdk.cli.serving
import
serve_http
# type: ignore
svc
.
inject_config
()
serve_http
(
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/cli/serve_dyn
e
mo.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/cli/serve_dyn
a
mo.py
View file @
602352ce
...
...
@@ -27,10 +27,10 @@ from typing import Any
import
click
from
dyn
e
mo.runtime
import
DistributedRuntime
,
dyn
e
mo_endpoint
,
dyn
e
mo_worker
from
dyn
e
mo.sdk
import
dyn
e
mo_context
from
dyn
a
mo.runtime
import
DistributedRuntime
,
dyn
a
mo_endpoint
,
dyn
a
mo_worker
from
dyn
a
mo.sdk
import
dyn
a
mo_context
logger
=
logging
.
getLogger
(
"dyn
e
mo.sdk.serve.dyn
e
mo"
)
logger
=
logging
.
getLogger
(
"dyn
a
mo.sdk.serve.dyn
a
mo"
)
logger
.
setLevel
(
logging
.
INFO
)
...
...
@@ -65,16 +65,16 @@ def main(
worker_env
:
str
|
None
,
worker_id
:
int
|
None
,
)
->
None
:
"""Start a worker for the given service - either Dyn
e
mo or regular service"""
"""Start a worker for the given service - either Dyn
a
mo or regular service"""
from
_bentoml_impl.loader
import
import_service
from
bentoml._internal.container
import
BentoMLContainer
from
bentoml._internal.context
import
server_context
from
bentoml._internal.log
import
configure_server_logging
run_id
=
generate_run_id
()
dyn
e
mo_context
[
"service_name"
]
=
service_name
dyn
e
mo_context
[
"runner_map"
]
=
runner_map
dyn
e
mo_context
[
"worker_id"
]
=
worker_id
dyn
a
mo_context
[
"service_name"
]
=
service_name
dyn
a
mo_context
[
"runner_map"
]
=
runner_map
dyn
a
mo_context
[
"worker_id"
]
=
worker_id
# Import service first to check configuration
service
=
import_service
(
bento_identifier
)
...
...
@@ -99,15 +99,15 @@ def main(
t
.
cast
(
t
.
Dict
[
str
,
str
],
json
.
loads
(
runner_map
))
)
# Check if Dyn
e
mo is enabled for this service
if
service
.
is_dyn
e
mo_component
():
# Check if Dyn
a
mo is enabled for this service
if
service
.
is_dyn
a
mo_component
():
if
worker_id
is
not
None
:
server_context
.
worker_index
=
worker_id
@
dyn
e
mo_worker
()
@
dyn
a
mo_worker
()
async
def
worker
(
runtime
:
DistributedRuntime
):
global
dyn
e
mo_context
dyn
e
mo_context
[
"runtime"
]
=
runtime
global
dyn
a
mo_context
dyn
a
mo_context
[
"runtime"
]
=
runtime
if
service_name
and
service_name
!=
service
.
name
:
server_context
.
service_type
=
"service"
else
:
...
...
@@ -115,8 +115,8 @@ def main(
server_context
.
service_name
=
service
.
name
# Get Dyn
e
mo configuration and create component
namespace
,
component_name
=
service
.
dyn
e
mo_address
()
# Get Dyn
a
mo configuration and create component
namespace
,
component_name
=
service
.
dyn
a
mo_address
()
logger
.
info
(
f
"[
{
run_id
}
] Registering component
{
namespace
}
/
{
component_name
}
"
)
...
...
@@ -132,32 +132,32 @@ def main(
dep
.
set_runtime
(
runtime
)
logger
.
info
(
f
"[
{
run_id
}
] Set runtime for dependency:
{
dep
}
"
)
# Then register all Dyn
e
mo endpoints
dyn
e
mo_endpoints
=
service
.
get_dyn
e
mo_endpoints
()
if
not
dyn
e
mo_endpoints
:
error_msg
=
f
"[
{
run_id
}
] FATAL ERROR: No Dyn
e
mo endpoints found in service
{
service
.
name
}
!"
# Then register all Dyn
a
mo endpoints
dyn
a
mo_endpoints
=
service
.
get_dyn
a
mo_endpoints
()
if
not
dyn
a
mo_endpoints
:
error_msg
=
f
"[
{
run_id
}
] FATAL ERROR: No Dyn
a
mo endpoints found in service
{
service
.
name
}
!"
logger
.
error
(
error_msg
)
raise
ValueError
(
error_msg
)
endpoints
=
[]
for
name
,
endpoint
in
dyn
e
mo_endpoints
.
items
():
for
name
,
endpoint
in
dyn
a
mo_endpoints
.
items
():
td_endpoint
=
component
.
endpoint
(
name
)
logger
.
info
(
f
"[
{
run_id
}
] Registering endpoint '
{
name
}
'"
)
endpoints
.
append
(
td_endpoint
)
# Bind an instance of inner to the endpoint
dyn
e
mo_context
[
"component"
]
=
component
dyn
e
mo_context
[
"endpoints"
]
=
endpoints
dyn
a
mo_context
[
"component"
]
=
component
dyn
a
mo_context
[
"endpoints"
]
=
endpoints
class_instance
=
service
.
inner
()
twm
=
[]
for
name
,
endpoint
in
dyn
e
mo_endpoints
.
items
():
for
name
,
endpoint
in
dyn
a
mo_endpoints
.
items
():
bound_method
=
endpoint
.
func
.
__get__
(
class_instance
)
# Only pass request type for now, use Any for response
# TODO: Handle a dyn
e
mo_endpoint not having types
# TODO: Handle a dyn
a
mo_endpoint not having types
# TODO: Handle multiple endpoints in a single component
dyn
e
mo_wrapped_method
=
dyn
e
mo_endpoint
(
endpoint
.
request_type
,
Any
)(
dyn
a
mo_wrapped_method
=
dyn
a
mo_endpoint
(
endpoint
.
request_type
,
Any
)(
bound_method
)
twm
.
append
(
dyn
e
mo_wrapped_method
)
twm
.
append
(
dyn
a
mo_wrapped_method
)
# Run startup hooks before setting up endpoints
for
name
,
member
in
vars
(
class_instance
.
__class__
).
items
():
if
callable
(
member
)
and
getattr
(
...
...
@@ -180,7 +180,7 @@ def main(
result
=
await
endpoints
[
0
].
serve_endpoint
(
twm
[
0
])
except
Exception
as
e
:
logger
.
error
(
f
"[
{
run_id
}
] Error in Dyn
e
mo component setup:
{
str
(
e
)
}
"
)
logger
.
error
(
f
"[
{
run_id
}
] Error in Dyn
a
mo component setup:
{
str
(
e
)
}
"
)
raise
asyncio
.
run
(
worker
())
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/cli/serving.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/cli/serving.py
View file @
602352ce
...
...
@@ -47,7 +47,7 @@ class ServiceProtocol(Protocol):
models
:
list
[
Any
]
bento
:
Any
def
is_dyn
e
mo_component
(
self
)
->
bool
:
def
is_dyn
a
mo_component
(
self
)
->
bool
:
...
...
...
@@ -155,7 +155,7 @@ def create_dependency_watcher(
return
watcher
,
socket
,
uri
def
create_dyn
e
mo_watcher
(
def
create_dyn
a
mo_watcher
(
bento_identifier
:
str
,
svc
:
ServiceProtocol
,
uds_path
:
str
,
...
...
@@ -165,7 +165,7 @@ def create_dynemo_watcher(
working_dir
:
Optional
[
str
]
=
None
,
env
:
Optional
[
Dict
[
str
,
str
]]
=
None
,
)
->
tuple
[
Watcher
,
CircusSocket
,
str
]:
"""Create a watcher for a Dyn
e
mo service in the dependency graph"""
"""Create a watcher for a Dyn
a
mo service in the dependency graph"""
from
bentoml.serving
import
create_watcher
# Get socket for this service
...
...
@@ -174,10 +174,10 @@ def create_dynemo_watcher(
# Get worker configuration
num_workers
,
worker_envs
=
scheduler
.
get_worker_env
(
svc
)
# Create Dyn
e
mo-specific worker args
# Create Dyn
a
mo-specific worker args
args
=
[
"-m"
,
"dyn
e
mo.sdk.cli.serve_dyn
e
mo"
,
# Use our Dyn
e
mo worker module
"dyn
a
mo.sdk.cli.serve_dyn
a
mo"
,
# Use our Dyn
a
mo worker module
bento_identifier
,
"--service-name"
,
svc
.
name
,
...
...
@@ -190,7 +190,7 @@ def create_dynemo_watcher(
# Create the watcher with dependency map in environment
watcher
=
create_watcher
(
name
=
f
"dyn
e
mo_service_
{
svc
.
name
}
"
,
name
=
f
"dyn
a
mo_service_
{
svc
.
name
}
"
,
args
=
args
,
numprocesses
=
num_workers
,
working_dir
=
working_dir
,
...
...
@@ -306,12 +306,12 @@ def serve_http(
if
name
in
dependency_map
:
continue
# Check if this is a Dyn
e
mo service
# Check if this is a Dyn
a
mo service
if
(
hasattr
(
dep_svc
,
"is_dyn
e
mo_component"
)
and
dep_svc
.
is_dyn
e
mo_component
()
hasattr
(
dep_svc
,
"is_dyn
a
mo_component"
)
and
dep_svc
.
is_dyn
a
mo_component
()
):
new_watcher
,
new_socket
,
uri
=
create_dyn
e
mo_watcher
(
new_watcher
,
new_socket
,
uri
=
create_dyn
a
mo_watcher
(
bento_id
,
dep_svc
,
uds_path
,
...
...
@@ -354,7 +354,7 @@ def serve_http(
except
ValueError
as
e
:
raise
BentoMLConfigException
(
f
"Invalid host IP address:
{
host
}
"
)
from
e
if
not
svc
.
is_dyn
e
mo_component
():
if
not
svc
.
is_dyn
a
mo_component
():
sockets
.
append
(
CircusSocket
(
name
=
API_SERVER_NAME
,
...
...
@@ -405,12 +405,12 @@ def serve_http(
scheme
=
"https"
if
BentoMLContainer
.
ssl
.
enabled
.
get
()
else
"http"
# Check if this is a Dyn
e
mo service
if
hasattr
(
svc
,
"is_dyn
e
mo_component"
)
and
svc
.
is_dyn
e
mo_component
():
# Create Dyn
e
mo-specific watcher using existing socket
# Check if this is a Dyn
a
mo service
if
hasattr
(
svc
,
"is_dyn
a
mo_component"
)
and
svc
.
is_dyn
a
mo_component
():
# Create Dyn
a
mo-specific watcher using existing socket
args
=
[
"-m"
,
"dyn
e
mo.sdk.cli.serve_dyn
e
mo"
,
# Use our Dyn
e
mo worker module
"dyn
a
mo.sdk.cli.serve_dyn
a
mo"
,
# Use our Dyn
a
mo worker module
bento_identifier
,
"--service-name"
,
svc
.
name
,
...
...
@@ -418,7 +418,7 @@ def serve_http(
"$(CIRCUS.WID)"
,
]
watcher
=
create_watcher
(
name
=
f
"dyn
e
mo_service_
{
svc
.
name
}
"
,
name
=
f
"dyn
a
mo_service_
{
svc
.
name
}
"
,
args
=
args
,
numprocesses
=
num_workers
,
working_dir
=
str
(
bento_path
.
absolute
()),
...
...
@@ -426,7 +426,7 @@ def serve_http(
env
=
env
,
# Dependency map will be injected by serve_http
)
watchers
.
append
(
watcher
)
print
(
f
"dyn
e
mo_service_
{
svc
.
name
}
entrypoint created"
)
print
(
f
"dyn
a
mo_service_
{
svc
.
name
}
entrypoint created"
)
else
:
# Create regular BentoML service watcher
watchers
.
append
(
...
...
@@ -473,14 +473,14 @@ def serve_http(
arbiter
.
exit_stack
.
callback
(
shutil
.
rmtree
,
uds_path
,
ignore_errors
=
True
)
arbiter
.
start
(
cb
=
lambda
_
:
logger
.
info
(
# type: ignore
"Starting Dyn
e
mo Service %s (%s/%s) listening on %s://%s:%d (Press CTRL+C to quit)"
if
(
hasattr
(
svc
,
"is_dyn
e
mo_component"
)
and
svc
.
is_dyn
e
mo_component
())
"Starting Dyn
a
mo Service %s (%s/%s) listening on %s://%s:%d (Press CTRL+C to quit)"
if
(
hasattr
(
svc
,
"is_dyn
a
mo_component"
)
and
svc
.
is_dyn
a
mo_component
())
else
'Starting production %s BentoServer from "%s" (Press CTRL+C to quit)'
,
*
(
(
svc
.
name
,
*
svc
.
dyn
e
mo_address
(),
scheme
,
log_host
,
port
)
(
svc
.
name
,
*
svc
.
dyn
a
mo_address
(),
scheme
,
log_host
,
port
)
if
(
hasattr
(
svc
,
"is_dyn
e
mo_component"
)
and
svc
.
is_dyn
e
mo_component
()
hasattr
(
svc
,
"is_dyn
a
mo_component"
)
and
svc
.
is_dyn
a
mo_component
()
)
else
(
scheme
.
upper
(),
bento_identifier
)
),
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/cli/start.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/cli/start.py
View file @
602352ce
...
...
@@ -238,7 +238,7 @@ def build_start_command() -> click.Group:
)
else
:
# for >=1.2 bentos
from
dyn
e
mo.sdk.cli.serving
import
serve_http
from
dyn
a
mo.sdk.cli.serving
import
serve_http
print
(
f
"Starting service
{
service_name
}
"
)
svc
.
inject_config
()
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/lib/__init__.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/lib/__init__.py
View file @
602352ce
File moved
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/lib/decorators.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/lib/decorators.py
View file @
602352ce
...
...
@@ -23,13 +23,13 @@ import bentoml
from
pydantic
import
BaseModel
class
Dyn
e
moEndpoint
:
"""Decorator class for Dyn
e
mo endpoints"""
class
Dyn
a
moEndpoint
:
"""Decorator class for Dyn
a
mo endpoints"""
def
__init__
(
self
,
func
:
t
.
Callable
,
name
:
str
|
None
=
None
):
self
.
func
=
func
self
.
name
=
name
or
func
.
__name__
self
.
is_dyn
e
mo_endpoint
=
True
self
.
is_dyn
a
mo_endpoint
=
True
# Extract request type from hints
hints
=
get_type_hints
(
func
)
...
...
@@ -50,7 +50,7 @@ class DynemoEndpoint:
if
isinstance
(
args
[
1
],
(
str
,
dict
)):
args
[
1
]
=
self
.
request_type
.
parse_obj
(
args
[
1
])
# type: ignore
# Convert Pydantic model to dict before passing to dyn
e
mo
# Convert Pydantic model to dict before passing to dyn
a
mo
if
len
(
args
)
>
1
and
isinstance
(
args
[
1
],
BaseModel
):
args
=
list
(
args
)
# type: ignore
args
[
1
]
=
args
[
1
].
model_dump
()
# type: ignore
...
...
@@ -58,31 +58,31 @@ class DynemoEndpoint:
return
await
self
.
func
(
*
args
,
**
kwargs
)
def
dyn
e
mo_endpoint
(
def
dyn
a
mo_endpoint
(
name
:
str
|
None
=
None
,
)
->
t
.
Callable
[[
t
.
Callable
],
Dyn
e
moEndpoint
]:
"""Decorator for Dyn
e
mo endpoints.
)
->
t
.
Callable
[[
t
.
Callable
],
Dyn
a
moEndpoint
]:
"""Decorator for Dyn
a
mo endpoints.
Args:
name: Optional name for the endpoint. Defaults to function name.
Example:
@dyn
e
mo_endpoint()
@dyn
a
mo_endpoint()
def my_endpoint(self, input: str) -> str:
return input
@dyn
e
mo_endpoint(name="custom_name")
@dyn
a
mo_endpoint(name="custom_name")
def another_endpoint(self, input: str) -> str:
return input
"""
def
decorator
(
func
:
t
.
Callable
)
->
Dyn
e
moEndpoint
:
return
Dyn
e
moEndpoint
(
func
,
name
)
def
decorator
(
func
:
t
.
Callable
)
->
Dyn
a
moEndpoint
:
return
Dyn
a
moEndpoint
(
func
,
name
)
return
decorator
def
dyn
e
mo_api
(
func
:
t
.
Callable
)
->
t
.
Callable
:
def
dyn
a
mo_api
(
func
:
t
.
Callable
)
->
t
.
Callable
:
"""Decorator for BentoML API endpoints.
Args:
...
...
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/lib/dependency.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/lib/dependency.py
View file @
602352ce
...
...
@@ -19,30 +19,30 @@ from typing import Any, Dict, Optional, TypeVar
from
_bentoml_sdk.service
import
Service
from
_bentoml_sdk.service.dependency
import
Dependency
from
dyn
e
mo.sdk.lib.service
import
Compound
Service
from
dyn
a
mo.sdk.lib.service
import
Dynamo
Service
T
=
TypeVar
(
"T"
)
class
Dyn
e
moClient
:
"""Client for calling Dyn
e
mo endpoints with streaming support"""
class
Dyn
a
moClient
:
"""Client for calling Dyn
a
mo endpoints with streaming support"""
def
__init__
(
self
,
service
:
Compound
Service
[
Any
]):
def
__init__
(
self
,
service
:
Dynamo
Service
[
Any
]):
self
.
_service
=
service
self
.
_endpoints
=
service
.
get_dyn
e
mo_endpoints
()
self
.
_dyn
e
mo_clients
:
Dict
[
str
,
Any
]
=
{}
self
.
_endpoints
=
service
.
get_dyn
a
mo_endpoints
()
self
.
_dyn
a
mo_clients
:
Dict
[
str
,
Any
]
=
{}
self
.
_runtime
=
None
def
__getattr__
(
self
,
name
:
str
)
->
Any
:
if
name
not
in
self
.
_endpoints
:
raise
AttributeError
(
f
"No Dyn
e
mo endpoint '
{
name
}
' found on service '
{
self
.
_service
.
name
}
'. "
f
"No Dyn
a
mo endpoint '
{
name
}
' found on service '
{
self
.
_service
.
name
}
'. "
f
"Available endpoints:
{
list
(
self
.
_endpoints
.
keys
())
}
"
)
# For streaming endpoints, create/cache the stream function
if
name
not
in
self
.
_dyn
e
mo_clients
:
namespace
,
component_name
=
self
.
_service
.
dyn
e
mo_address
()
if
name
not
in
self
.
_dyn
a
mo_clients
:
namespace
,
component_name
=
self
.
_service
.
dyn
a
mo_address
()
# Create async generator function that uses Queue for streaming
async
def
get_stream
(
*
args
,
**
kwargs
):
...
...
@@ -61,8 +61,9 @@ class DynemoClient:
# TODO: Potentially model dump for a user here so they can pass around Pydantic models
stream
=
await
client
.
generate
(
*
args
,
**
kwargs
)
print
(
"here8"
,
stream
,
flush
=
True
)
async
for
item
in
stream
:
print
(
item
,
flush
=
True
)
data
=
item
.
data
()
print
(
f
"Item data:
{
data
}
"
)
await
queue
.
put
(
data
)
...
...
@@ -72,10 +73,10 @@ class DynemoClient:
raise
else
:
# Create dyn
e
mo worker if no runtime
from
dyn
e
mo.runtime
import
DistributedRuntime
,
dyn
e
mo_worker
# Create dyn
a
mo worker if no runtime
from
dyn
a
mo.runtime
import
DistributedRuntime
,
dyn
a
mo_worker
@
dyn
e
mo_worker
()
@
dyn
a
mo_worker
()
async
def
stream_worker
(
runtime
:
DistributedRuntime
):
try
:
# Store runtime for future use
...
...
@@ -89,8 +90,9 @@ class DynemoClient:
)
stream
=
await
client
.
generate
(
*
args
,
**
kwargs
)
print
(
stream
,
flush
=
True
)
async
for
item
in
stream
:
print
(
item
,
flush
=
True
)
data
=
item
.
data
()
print
(
f
"Item data:
{
data
}
"
)
await
queue
.
put
(
data
)
...
...
@@ -115,13 +117,13 @@ class DynemoClient:
except
Exception
:
raise
self
.
_dyn
e
mo_clients
[
name
]
=
get_stream
self
.
_dyn
a
mo_clients
[
name
]
=
get_stream
return
self
.
_dyn
e
mo_clients
[
name
]
return
self
.
_dyn
a
mo_clients
[
name
]
class
Dyn
e
moDependency
(
Dependency
[
T
]):
"""Enhanced dependency that supports Dyn
e
mo endpoints"""
class
Dyn
a
moDependency
(
Dependency
[
T
]):
"""Enhanced dependency that supports Dyn
a
mo endpoints"""
def
__init__
(
self
,
...
...
@@ -131,7 +133,7 @@ class DynemoDependency(Dependency[T]):
cluster
:
str
|
None
=
None
,
):
super
().
__init__
(
on
,
url
=
url
,
deployment
=
deployment
,
cluster
=
cluster
)
self
.
_dyn
e
mo_client
:
Optional
[
Dyn
e
moClient
]
=
None
self
.
_dyn
a
mo_client
:
Optional
[
Dyn
a
moClient
]
=
None
self
.
_runtime
=
None
# offers an escape hatch to get the endpoint directly
...
...
@@ -143,7 +145,7 @@ class DynemoDependency(Dependency[T]):
...
await dep.get_endpoint("generate") # equivalent to the following
router_client = (
await runtime.namespace("dyn
e
mo-init")
await runtime.namespace("dyn
a
mo-init")
.component("router")
.endpoint("generate")
.client()
...
...
@@ -153,13 +155,13 @@ class DynemoDependency(Dependency[T]):
# TODO: Read the runtime from the tdist since it is not stored in global
if
self
.
_runtime
is
None
:
print
(
"Get Endpoint: Runtime not set for Dyn
e
moDependency. Cannot get endpoint."
"Get Endpoint: Runtime not set for Dyn
a
moDependency. Cannot get endpoint."
)
raise
ValueError
(
"Runtime not set for Dyn
e
moDependency"
)
raise
ValueError
(
"Runtime not set for Dyn
a
moDependency"
)
address
=
self
.
on
.
dyn
e
mo_address
()
address
=
self
.
on
.
dyn
a
mo_address
()
comp_ns
,
comp_name
=
address
print
(
"Get Endpoint: Dyn
e
mo ADDRESS: "
,
address
)
print
(
"Get Endpoint: Dyn
a
mo ADDRESS: "
,
address
)
return
(
await
self
.
_runtime
.
namespace
(
comp_ns
)
.
component
(
comp_name
)
...
...
@@ -168,19 +170,19 @@ class DynemoDependency(Dependency[T]):
)
def
set_runtime
(
self
,
runtime
:
Any
)
->
None
:
"""Set the Dyn
e
mo runtime for this dependency"""
"""Set the Dyn
a
mo runtime for this dependency"""
self
.
_runtime
=
runtime
if
self
.
_dyn
e
mo_client
:
self
.
_dyn
e
mo_client
.
_runtime
=
runtime
if
self
.
_dyn
a
mo_client
:
self
.
_dyn
a
mo_client
.
_runtime
=
runtime
def
get
(
self
,
*
args
:
Any
,
**
kwargs
:
Any
)
->
T
|
Any
:
# If this is a Dyn
e
mo-enabled service, return the Dyn
e
mo client
if
isinstance
(
self
.
on
,
Compound
Service
)
and
self
.
on
.
is_dyn
e
mo_component
():
if
self
.
_dyn
e
mo_client
is
None
:
self
.
_dyn
e
mo_client
=
Dyn
e
moClient
(
self
.
on
)
# If this is a Dyn
a
mo-enabled service, return the Dyn
a
mo client
if
isinstance
(
self
.
on
,
Dynamo
Service
)
and
self
.
on
.
is_dyn
a
mo_component
():
if
self
.
_dyn
a
mo_client
is
None
:
self
.
_dyn
a
mo_client
=
Dyn
a
moClient
(
self
.
on
)
if
self
.
_runtime
:
self
.
_dyn
e
mo_client
.
_runtime
=
self
.
_runtime
return
self
.
_dyn
e
mo_client
self
.
_dyn
a
mo_client
.
_runtime
=
self
.
_runtime
return
self
.
_dyn
a
mo_client
# Otherwise fall back to normal BentoML dependency resolution
return
super
().
get
(
*
args
,
**
kwargs
)
...
...
@@ -192,11 +194,11 @@ def depends(
url
:
str
|
None
=
None
,
deployment
:
str
|
None
=
None
,
cluster
:
str
|
None
=
None
,
)
->
Dyn
e
moDependency
[
T
]:
"""Create a dependency that's Dyn
e
mo-aware.
)
->
Dyn
a
moDependency
[
T
]:
"""Create a dependency that's Dyn
a
mo-aware.
If the dependency is on a Dyn
e
mo-enabled service, this will return a client
that can call Dyn
e
mo endpoints. Otherwise behaves like normal BentoML dependency.
If the dependency is on a Dyn
a
mo-enabled service, this will return a client
that can call Dyn
a
mo endpoints. Otherwise behaves like normal BentoML dependency.
Args:
on: The service to depend on
...
...
@@ -205,8 +207,8 @@ def depends(
cluster: Cluster name
Raises:
AttributeError: When trying to call a non-existent Dyn
e
mo endpoint
AttributeError: When trying to call a non-existent Dyn
a
mo endpoint
"""
if
on
is
not
None
and
not
isinstance
(
on
,
Service
):
raise
TypeError
(
"depends() expects a class decorated with @service()"
)
return
Dyn
e
moDependency
(
on
,
url
=
url
,
deployment
=
deployment
,
cluster
=
cluster
)
return
Dyn
a
moDependency
(
on
,
url
=
url
,
deployment
=
deployment
,
cluster
=
cluster
)
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/lib/image.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/lib/image.py
View file @
602352ce
...
...
@@ -13,13 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# wrapper over bento images to handle Dyn
e
mo base image
# wrapper over bento images to handle Dyn
a
mo base image
import
os
import
bentoml
# TODO: "dyn
e
mo:latest-vllm" image will not be available to image builder in k8s
# TODO: "dyn
a
mo:latest-vllm" image will not be available to image builder in k8s
# so We'd consider publishing the base image for releases to public nvcr.io registry.
image_name
=
os
.
getenv
(
"DYNEMO_IMAGE"
,
"dyn
e
mo:latest-vllm"
)
image_name
=
os
.
getenv
(
"DYNEMO_IMAGE"
,
"dyn
a
mo:latest-vllm"
)
DYNEMO_IMAGE
=
bentoml
.
images
.
PythonImage
(
base_image
=
image_name
)
deploy/dyn
e
mo/sdk/src/dyn
e
mo/sdk/lib/service.py
→
deploy/dyn
a
mo/sdk/src/dyn
a
mo/sdk/lib/service.py
View file @
602352ce
...
...
@@ -22,22 +22,22 @@ from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union
from
_bentoml_sdk
import
Service
,
ServiceConfig
from
_bentoml_sdk.images
import
Image
from
dyn
e
mo.sdk.lib.decorators
import
Dyn
e
moEndpoint
from
dyn
a
mo.sdk.lib.decorators
import
Dyn
a
moEndpoint
T
=
TypeVar
(
"T"
,
bound
=
object
)
@
dataclass
class
Dyn
e
moConfig
:
"""Configuration for Dyn
e
mo components"""
class
Dyn
a
moConfig
:
"""Configuration for Dyn
a
mo components"""
enabled
:
bool
=
False
name
:
str
|
None
=
None
namespace
:
str
|
None
=
None
class
Compound
Service
(
Service
[
T
]):
"""A custom service class that extends BentoML's base Service with Dyn
e
mo capabilities"""
class
Dynamo
Service
(
Service
[
T
]):
"""A custom service class that extends BentoML's base Service with Dyn
a
mo capabilities"""
def
__init__
(
self
,
...
...
@@ -45,71 +45,71 @@ class CompoundService(Service[T]):
inner
:
type
[
T
],
image
:
Optional
[
Image
]
=
None
,
envs
:
Optional
[
list
[
dict
[
str
,
Any
]]]
=
None
,
dyn
e
mo_config
:
Optional
[
Dyn
e
moConfig
]
=
None
,
dyn
a
mo_config
:
Optional
[
Dyn
a
moConfig
]
=
None
,
):
super
().
__init__
(
config
=
config
,
inner
=
inner
,
image
=
image
,
envs
=
envs
or
[])
# Initialize Dyn
e
mo configuration
self
.
_dyn
e
mo_config
=
(
dyn
e
mo_config
if
dyn
e
mo_config
else
Dyn
e
moConfig
(
name
=
inner
.
__name__
,
namespace
=
"default"
)
# Initialize Dyn
a
mo configuration
self
.
_dyn
a
mo_config
=
(
dyn
a
mo_config
if
dyn
a
mo_config
else
Dyn
a
moConfig
(
name
=
inner
.
__name__
,
namespace
=
"default"
)
)
if
self
.
_dyn
e
mo_config
.
name
is
None
:
self
.
_dyn
e
mo_config
.
name
=
inner
.
__name__
if
self
.
_dyn
a
mo_config
.
name
is
None
:
self
.
_dyn
a
mo_config
.
name
=
inner
.
__name__
# Register Dyn
e
mo endpoints
self
.
_dyn
e
mo_endpoints
:
Dict
[
str
,
Dyn
e
moEndpoint
]
=
{}
# Register Dyn
a
mo endpoints
self
.
_dyn
a
mo_endpoints
:
Dict
[
str
,
Dyn
a
moEndpoint
]
=
{}
for
field
in
dir
(
inner
):
value
=
getattr
(
inner
,
field
)
if
isinstance
(
value
,
Dyn
e
moEndpoint
):
self
.
_dyn
e
mo_endpoints
[
value
.
name
]
=
value
if
isinstance
(
value
,
Dyn
a
moEndpoint
):
self
.
_dyn
a
mo_endpoints
[
value
.
name
]
=
value
def
is_dyn
e
mo_component
(
self
)
->
bool
:
"""Check if this service is configured as a Dyn
e
mo component"""
return
self
.
_dyn
e
mo_config
.
enabled
def
is_dyn
a
mo_component
(
self
)
->
bool
:
"""Check if this service is configured as a Dyn
a
mo component"""
return
self
.
_dyn
a
mo_config
.
enabled
def
dyn
e
mo_address
(
self
)
->
Tuple
[
Optional
[
str
],
Optional
[
str
]]:
"""Get the Dyn
e
mo address for this component in namespace/name format"""
if
not
self
.
is_dyn
e
mo_component
():
raise
ValueError
(
"Service is not configured as a Dyn
e
mo component"
)
def
dyn
a
mo_address
(
self
)
->
Tuple
[
Optional
[
str
],
Optional
[
str
]]:
"""Get the Dyn
a
mo address for this component in namespace/name format"""
if
not
self
.
is_dyn
a
mo_component
():
raise
ValueError
(
"Service is not configured as a Dyn
a
mo component"
)
# Check if we have a runner map with Dyn
e
mo address
# Check if we have a runner map with Dyn
a
mo address
runner_map
=
os
.
environ
.
get
(
"BENTOML_RUNNER_MAP"
)
if
runner_map
:
try
:
runners
=
json
.
loads
(
runner_map
)
if
self
.
name
in
runners
:
address
=
runners
[
self
.
name
]
if
address
.
startswith
(
"dyn
e
mo://"
):
# Parse dyn
e
mo://namespace/name into (namespace, name)
if
address
.
startswith
(
"dyn
a
mo://"
):
# Parse dyn
a
mo://namespace/name into (namespace, name)
_
,
path
=
address
.
split
(
"://"
,
1
)
namespace
,
name
=
path
.
split
(
"/"
,
1
)
print
(
f
"Resolved Dyn
e
mo address from runner map:
{
namespace
}
/
{
name
}
"
f
"Resolved Dyn
a
mo address from runner map:
{
namespace
}
/
{
name
}
"
)
return
(
namespace
,
name
)
except
(
json
.
JSONDecodeError
,
ValueError
)
as
e
:
raise
ValueError
(
f
"Failed to parse BENTOML_RUNNER_MAP:
{
str
(
e
)
}
"
)
from
e
print
(
f
"Using default Dyn
e
mo address:
{
self
.
_dyn
e
mo_config
.
namespace
}
/
{
self
.
_dyn
e
mo_config
.
name
}
"
f
"Using default Dyn
a
mo address:
{
self
.
_dyn
a
mo_config
.
namespace
}
/
{
self
.
_dyn
a
mo_config
.
name
}
"
)
return
(
self
.
_dyn
e
mo_config
.
namespace
,
self
.
_dyn
e
mo_config
.
name
)
return
(
self
.
_dyn
a
mo_config
.
namespace
,
self
.
_dyn
a
mo_config
.
name
)
def
get_dyn
e
mo_endpoints
(
self
)
->
Dict
[
str
,
Dyn
e
moEndpoint
]:
"""Get all registered Dyn
e
mo endpoints"""
return
self
.
_dyn
e
mo_endpoints
def
get_dyn
a
mo_endpoints
(
self
)
->
Dict
[
str
,
Dyn
a
moEndpoint
]:
"""Get all registered Dyn
a
mo endpoints"""
return
self
.
_dyn
a
mo_endpoints
def
get_dyn
e
mo_endpoint
(
self
,
name
:
str
)
->
Dyn
e
moEndpoint
:
"""Get a specific Dyn
e
mo endpoint by name"""
if
name
not
in
self
.
_dyn
e
mo_endpoints
:
raise
ValueError
(
f
"No Dyn
e
mo endpoint found with name:
{
name
}
"
)
return
self
.
_dyn
e
mo_endpoints
[
name
]
def
get_dyn
a
mo_endpoint
(
self
,
name
:
str
)
->
Dyn
a
moEndpoint
:
"""Get a specific Dyn
a
mo endpoint by name"""
if
name
not
in
self
.
_dyn
a
mo_endpoints
:
raise
ValueError
(
f
"No Dyn
a
mo endpoint found with name:
{
name
}
"
)
return
self
.
_dyn
a
mo_endpoints
[
name
]
def
list_dyn
e
mo_endpoints
(
self
)
->
List
[
str
]:
"""List names of all registered Dyn
e
mo endpoints"""
return
list
(
self
.
_dyn
e
mo_endpoints
.
keys
())
def
list_dyn
a
mo_endpoints
(
self
)
->
List
[
str
]:
"""List names of all registered Dyn
a
mo endpoints"""
return
list
(
self
.
_dyn
a
mo_endpoints
.
keys
())
# todo: add another function to bind an instance of the inner to the self within these methods
...
...
@@ -120,13 +120,13 @@ def service(
*
,
image
:
Optional
[
Image
]
=
None
,
envs
:
Optional
[
list
[
dict
[
str
,
Any
]]]
=
None
,
dyn
e
mo
:
Optional
[
Union
[
Dict
[
str
,
Any
],
Dyn
e
moConfig
]]
=
None
,
dyn
a
mo
:
Optional
[
Union
[
Dict
[
str
,
Any
],
Dyn
a
moConfig
]]
=
None
,
**
kwargs
:
Any
,
)
->
Any
:
"""Enhanced service decorator that supports Dyn
e
mo configuration
"""Enhanced service decorator that supports Dyn
a
mo configuration
Args:
dyn
e
mo: Dyn
e
mo configuration, either as a Dyn
e
moConfig object or dict with keys:
dyn
a
mo: Dyn
a
mo configuration, either as a Dyn
a
moConfig object or dict with keys:
- enabled: bool (default True)
- name: str (default: class name)
- namespace: str (default: "default")
...
...
@@ -134,23 +134,23 @@ def service(
"""
config
=
kwargs
# Parse dict into Dyn
e
moConfig object
dyn
e
mo_config
:
Optional
[
Dyn
e
moConfig
]
=
None
if
dyn
e
mo
is
not
None
:
if
isinstance
(
dyn
e
mo
,
dict
):
dyn
e
mo_config
=
Dyn
e
moConfig
(
**
dyn
e
mo
)
# Parse dict into Dyn
a
moConfig object
dyn
a
mo_config
:
Optional
[
Dyn
a
moConfig
]
=
None
if
dyn
a
mo
is
not
None
:
if
isinstance
(
dyn
a
mo
,
dict
):
dyn
a
mo_config
=
Dyn
a
moConfig
(
**
dyn
a
mo
)
else
:
dyn
e
mo_config
=
dyn
e
mo
dyn
a
mo_config
=
dyn
a
mo
def
decorator
(
inner
:
type
[
T
])
->
Compound
Service
[
T
]:
def
decorator
(
inner
:
type
[
T
])
->
Dynamo
Service
[
T
]:
if
isinstance
(
inner
,
Service
):
raise
TypeError
(
"service() decorator can only be applied once"
)
return
Compound
Service
(
return
Dynamo
Service
(
config
=
config
,
inner
=
inner
,
image
=
image
,
envs
=
envs
or
[],
dyn
e
mo_config
=
dyn
e
mo_config
,
dyn
a
mo_config
=
dyn
a
mo_config
,
)
return
decorator
(
inner
)
if
inner
is
not
None
else
decorator
deploy/dyn
e
mo/sdk/uv.lock
→
deploy/dyn
a
mo/sdk/uv.lock
View file @
602352ce
...
...
@@ -316,7 +316,7 @@ wheels = [
]
[[package]]
name = "dyn
e
mo-sdk"
name = "dyn
a
mo-sdk"
version = "0.1.0"
source = { editable = "." }
dependencies = [
...
...
deploy/dynemo/api-server/.air.toml
deleted
100644 → 0
View file @
ecf53ce2
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
root
=
"."
testdata_dir
=
"testdata"
tmp_dir
=
"tmp"
[build]
args_bin
=
[]
bin
=
"./tmp/main"
cmd
=
"go build -o ./tmp/main ./api"
delay
=
1000
exclude_dir
=
[
"assets"
,
"tmp"
,
"vendor"
,
"testdata"
]
exclude_file
=
[]
exclude_regex
=
["_test.go"]
exclude_unchanged
=
false
follow_symlink
=
false
full_bin
=
""
include_dir
=
[]
include_ext
=
[
"go"
,
"tpl"
,
"tmpl"
,
"html"
]
include_file
=
[]
kill_delay
=
"0s"
log
=
"build-errors.log"
poll
=
false
poll_interval
=
0
post_cmd
=
[]
pre_cmd
=
[]
rerun
=
false
rerun_delay
=
500
send_interrupt
=
false
stop_on_error
=
false
[color]
app
=
""
build
=
"yellow"
main
=
"magenta"
runner
=
"green"
watcher
=
"cyan"
[log]
main_only
=
false
time
=
false
[misc]
clean_on_exit
=
false
[proxy]
app_port
=
0
enabled
=
false
proxy_port
=
0
[screen]
clear_on_rebuild
=
false
keep_scroll
=
true
deploy/dynemo/api-server/.env
deleted
100644 → 0
View file @
ecf53ce2
# Local development env
DB_USER="postgres"
DB_PASSWORD="pgadmin"
DB_HOST="localhost"
DB_PORT=5432
DB_NAME="postgres"
DMS_HOST="localhost"
DMS_PORT=8080
NDS_HOST="localhost"
NDS_PORT=8001
DEFAULT_KUBE_NAMESPACE="compoundai"
deploy/dynemo/api-server/.gitignore
deleted
100644 → 0
View file @
ecf53ce2
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/*
Dockerfile.cross
# Test binary, built with `go test -c`
*.test
# Temporary folder used by Air
tmp
\ No newline at end of file
deploy/dynemo/api-server/Dockerfile
deleted
100644 → 0
View file @
ecf53ce2
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Build the manager binary
FROM
golang:1.23 AS builder
ARG
TARGETOS
ARG
TARGETARCH
WORKDIR
/workspace
# Copy the Go Modules manifests
COPY
go.mod go.mod
COPY
go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN
go mod download
# Copy the go source
COPY
api/ api/
COPY
.env .env
# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN
CGO_ENABLED
=
0
GOOS
=
${
TARGETOS
:-
linux
}
GOARCH
=
${
TARGETARCH
}
go build
-a
-o
server api/main.go
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM
gcr.io/distroless/static:nonroot
WORKDIR
/
COPY
--from=builder /workspace/server .
COPY
--from=builder /workspace/.env .
USER
65532:65532
ENTRYPOINT
["/server"]
deploy/dynemo/api-server/Earthfile
deleted
100644 → 0
View file @
ecf53ce2
VERSION 0.8
build:
FROM golang:1.23
ARG TARGETOS
ARG TARGETARCH
WORKDIR /workspace
COPY go.mod go.mod
COPY go.sum go.sum
RUN go mod download
COPY api/ api/
COPY .env .env
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o server api/main.go
SAVE ARTIFACT /workspace/server
SAVE ARTIFACT /workspace/.env
#TODO: mkhadkevich earthly tests fail https://gitlab-master.nvidia.com/aire/microservices/compoundai/-/jobs/144475821
#test:
# FROM +build
# # copy test files
# COPY tests/ tests/
# RUN go test ./...
docker:
ARG CI_REGISTRY_IMAGE=my-registry
ARG CI_COMMIT_SHA=latest
ARG IMAGE=compound-api-server
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY +build/server .
COPY +build/.env .
USER 65532:65532
ENTRYPOINT ["/server"]
SAVE IMAGE --push $CI_REGISTRY_IMAGE/$IMAGE:$CI_COMMIT_SHA
\ No newline at end of file
Prev
1
2
3
4
5
6
7
8
9
10
…
22
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment