66from typing import Annotated , Any
77from urllib .parse import quote
88
9- from locust import HttpUser , run_single_user , task
9+ from common .base_user import OsparcWebUserBase
10+ from locust import run_single_user , task
1011from pydantic import BaseModel , Field
11- from pydantic_settings import BaseSettings , SettingsConfigDict
12- from requests .auth import HTTPBasicAuth
1312from tenacity import retry , retry_if_exception_type , stop_after_delay , wait_exponential
1413from urllib3 import PoolManager , Retry
1514
16-
17- class UserSettings (BaseSettings ):
18- model_config = SettingsConfigDict (extra = "ignore" )
19- OSPARC_API_KEY : Annotated [str , Field ()] # required, no default
20- OSPARC_API_SECRET : Annotated [str , Field ()] # required, no default
21-
22-
2315_SOLVER_KEY = "simcore/services/comp/osparc-python-runner"
2416_SOLVER_VERSION = "1.2.0"
2517
@@ -61,13 +53,11 @@ class Function(BaseModel):
6153 solver_version : Annotated [str , Field ()] = _SOLVER_VERSION
6254
6355
64- class MetaModelingUser (HttpUser ):
56+ class MetaModelingUser (OsparcWebUserBase ):
57+ # This overrides the class attribute in OsparcWebUserBase
58+ requires_login = True
59+
6560 def __init__ (self , * args , ** kwargs ):
66- self ._user_settings = UserSettings ()
67- self ._auth = HTTPBasicAuth (
68- username = self ._user_settings .OSPARC_API_KEY ,
69- password = self ._user_settings .OSPARC_API_SECRET ,
70- )
7161 retry_strategy = Retry (
7262 total = 4 ,
7363 backoff_factor = 4.0 ,
@@ -98,28 +88,24 @@ def __init__(self, *args, **kwargs):
9888
9989 def on_stop (self ) -> None :
10090 if self ._script is not None :
101- self .client . delete (
91+ self .authenticated_delete (
10292 f"/v0/files/{ self ._script .get ('id' )} " ,
10393 name = "/v0/files/[file_id]" ,
104- auth = self ._auth ,
10594 )
10695 if self ._input_json is not None :
107- self .client . delete (
96+ self .authenticated_delete (
10897 f"/v0/files/{ self ._input_json .get ('id' )} " ,
10998 name = "/v0/files/[file_id]" ,
110- auth = self ._auth ,
11199 )
112100 if self ._function_uid is not None :
113- self .client . delete (
101+ self .authenticated_delete (
114102 f"/v0/functions/{ self ._function_uid } " ,
115103 name = "/v0/functions/[function_uid]" ,
116- auth = self ._auth ,
117104 )
118105 if self ._run_uid is not None :
119- self .client . delete (
106+ self .authenticated_delete (
120107 f"/v0/function_jobs/{ self ._run_uid } " ,
121108 name = "/v0/function_jobs/[function_run_uid]" ,
122- auth = self ._auth ,
123109 )
124110
125111 @task
@@ -139,17 +125,14 @@ def run_function(self):
139125 description = "Test function" ,
140126 default_inputs = {"input_1" : self ._script },
141127 )
142- response = self .client .post (
143- "/v0/functions" , json = _function .model_dump (), auth = self ._auth
144- )
128+ response = self .authenticated_post ("/v0/functions" , json = _function .model_dump ())
145129 response .raise_for_status ()
146130 self ._function_uid = response .json ().get ("uid" )
147131 assert self ._function_uid is not None
148132
149- response = self .client . post (
133+ response = self .authenticated_post (
150134 f"/v0/functions/{ self ._function_uid } :run" ,
151135 json = {"input_2" : self ._input_json },
152- auth = self ._auth ,
153136 name = "/v0/functions/[function_uid]:run" ,
154137 )
155138 response .raise_for_status ()
@@ -160,9 +143,8 @@ def run_function(self):
160143
161144 self .wait_until_done ()
162145
163- response = self .client . get (
146+ response = self .authenticated_get (
164147 f"/v0/solvers/{ quote (_SOLVER_KEY , safe = '' )} /releases/{ _SOLVER_VERSION } /jobs/{ self ._solver_job_uid } /outputs" ,
165- auth = self ._auth ,
166148 name = "/v0/solvers/[solver_key]/releases/[solver_version]/jobs/[solver_job_id]/outputs" ,
167149 )
168150 response .raise_for_status ()
@@ -174,9 +156,8 @@ def run_function(self):
174156 reraise = False ,
175157 )
176158 def wait_until_done (self ):
177- response = self .client . get (
159+ response = self .authenticated_get (
178160 f"/v0/function_jobs/{ self ._run_uid } /status" ,
179- auth = self ._auth ,
180161 name = "/v0/function_jobs/[function_run_uid]/status" ,
181162 )
182163 response .raise_for_status ()
@@ -187,9 +168,7 @@ def upload_file(self, file: Path) -> dict[str, str]:
187168 assert file .is_file ()
188169 with file .open (mode = "rb" ) as f :
189170 files = {"file" : f }
190- response = self .client .put (
191- "/v0/files/content" , files = files , auth = self ._auth
192- )
171+ response = self .authenticated_put ("/v0/files/content" , files = files )
193172 response .raise_for_status ()
194173 assert response .json ().get ("id" ) is not None
195174 return response .json ()
0 commit comments