4343DEFAULT_RETRY_DELAY_SECONDS = 2.5
4444DEFAULT_MAX_FAILURES_PER_WINDOW = 20
4545DEFAULT_FAILURE_WINDOW_SECONDS = 60.0
46+ DEFAULT_PRICE_PER_UNIT = 0
47+ DEFAULT_PIXELS_PER_UNIT = 1
48+ DEFAULT_PRICE_UNIT = "USD"
4649CHANNEL_MIME_JSONL = "application/jsonl"
4750
4851_registration : LiveRunnerRegistration | None = None
@@ -65,6 +68,9 @@ class ScopeRunnerSettings:
6568 retry_delay_seconds : float = DEFAULT_RETRY_DELAY_SECONDS
6669 max_failures_per_window : int = DEFAULT_MAX_FAILURES_PER_WINDOW
6770 failure_window_seconds : float = DEFAULT_FAILURE_WINDOW_SECONDS
71+ price_per_unit : int = DEFAULT_PRICE_PER_UNIT
72+ pixels_per_unit : int = DEFAULT_PIXELS_PER_UNIT
73+ price_unit : str = DEFAULT_PRICE_UNIT
6874
6975 def resolved_runner_url (self ) -> str :
7076 if self .runner_url :
@@ -89,11 +95,35 @@ class ScopeBridgeSession:
8995settings = ScopeRunnerSettings ()
9096
9197
98+ def _env_int (name : str , default : int ) -> int :
99+ raw = os .getenv (name )
100+ if raw is None :
101+ return default
102+ try :
103+ return int (raw )
104+ except ValueError as exc :
105+ raise ValueError (f"{ name } must be an integer" ) from exc
106+
107+
108+ def _validate_price_settings (price_per_unit : int , pixels_per_unit : int ) -> None :
109+ if pixels_per_unit <= 0 :
110+ raise ValueError ("LIVEPEER_RUNNER_PIXELS_PER_UNIT must be positive" )
111+
112+
92113def _settings_from_env () -> ScopeRunnerSettings :
93114 port = int (os .getenv ("LIVEPEER_RUNNER_PORT" , str (DEFAULT_PORT )))
94115 inner_port = int (os .getenv ("LIVEPEER_INNER_PORT" , str (DEFAULT_INNER_PORT )))
95116 host = os .getenv ("LIVEPEER_RUNNER_HOST" , DEFAULT_HOST )
96117 runner_url = os .getenv ("LIVEPEER_RUNNER_URL" , "" )
118+ price_per_unit = _env_int (
119+ "LIVEPEER_RUNNER_PRICE_PER_UNIT" ,
120+ DEFAULT_PRICE_PER_UNIT ,
121+ )
122+ pixels_per_unit = _env_int (
123+ "LIVEPEER_RUNNER_PIXELS_PER_UNIT" ,
124+ DEFAULT_PIXELS_PER_UNIT ,
125+ )
126+ _validate_price_settings (price_per_unit , pixels_per_unit )
97127 inner_ws_url = os .getenv (
98128 "LIVEPEER_INNER_WS_URL" ,
99129 f"ws://127.0.0.1:{ inner_port } /ws" ,
@@ -110,6 +140,9 @@ def _settings_from_env() -> ScopeRunnerSettings:
110140 inner_port = inner_port
111141 if "LIVEPEER_INNER_PORT" in os .environ
112142 else parsed_inner_port ,
143+ price_per_unit = price_per_unit ,
144+ pixels_per_unit = pixels_per_unit ,
145+ price_unit = os .getenv ("LIVEPEER_RUNNER_PRICE_UNIT" , DEFAULT_PRICE_UNIT ),
113146 )
114147
115148
@@ -144,6 +177,9 @@ async def _register_runner(
144177 secret = runner_settings .orch_secret ,
145178 runner_url = runner_settings .resolved_runner_url (),
146179 app = LIVEPEER_APP_NAME ,
180+ price_per_unit = runner_settings .price_per_unit ,
181+ pixels_per_unit = runner_settings .pixels_per_unit ,
182+ price_unit = runner_settings .price_unit ,
147183 mode = "persistent" ,
148184 capacity = 1 ,
149185 on_session_release = _on_session_release ,
@@ -729,17 +765,44 @@ def _on_session_release(event: Any) -> None:
729765 show_default = True ,
730766 help = "Inner Scope runner websocket URL" ,
731767)
768+ @click .option (
769+ "--price-per-unit" ,
770+ envvar = "LIVEPEER_RUNNER_PRICE_PER_UNIT" ,
771+ default = DEFAULT_PRICE_PER_UNIT ,
772+ show_default = True ,
773+ type = int ,
774+ help = "Runner price per unit advertised to the orchestrator" ,
775+ )
776+ @click .option (
777+ "--pixels-per-unit" ,
778+ envvar = "LIVEPEER_RUNNER_PIXELS_PER_UNIT" ,
779+ default = DEFAULT_PIXELS_PER_UNIT ,
780+ show_default = True ,
781+ type = int ,
782+ help = "Pixels per advertised price unit" ,
783+ )
784+ @click .option (
785+ "--price-unit" ,
786+ envvar = "LIVEPEER_RUNNER_PRICE_UNIT" ,
787+ default = DEFAULT_PRICE_UNIT ,
788+ show_default = True ,
789+ help = "Currency unit for advertised runner price" ,
790+ )
732791def main (
733792 host : str ,
734793 port : int ,
735794 orchestrator : str ,
736795 orch_secret : str ,
737796 runner_url : str ,
738797 inner_ws_url : str ,
798+ price_per_unit : int ,
799+ pixels_per_unit : int ,
800+ price_unit : str ,
739801) -> None :
740802 """Run the Livepeer Scope live-runner app."""
741803 global settings
742804 logging .basicConfig (level = logging .INFO )
805+ _validate_price_settings (price_per_unit , pixels_per_unit )
743806 inner_host , inner_port = _inner_bind_from_ws_url (inner_ws_url )
744807 settings = ScopeRunnerSettings (
745808 host = host ,
@@ -750,6 +813,9 @@ def main(
750813 inner_ws_url = inner_ws_url ,
751814 inner_host = inner_host ,
752815 inner_port = inner_port ,
816+ price_per_unit = price_per_unit ,
817+ pixels_per_unit = pixels_per_unit ,
818+ price_unit = price_unit ,
753819 )
754820 uvicorn .run (
755821 "scope.cloud.livepeer_scope_app:app" ,
0 commit comments