Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions routers/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ async def delete_controller(controller_type: ControllerType, controller_name: st
)


@router.get("/{controller_type}/{controller_name}/config/template", response_model=Dict)
@router.get("/{controller_type}/{controller_name}/config/template")
async def get_controller_config_template(controller_type: ControllerType, controller_name: str):
"""
Get controller configuration template with default values.
Expand All @@ -241,10 +241,40 @@ async def get_controller_config_template(controller_type: ControllerType, contro
)

# Extract fields and default values
config_fields = {name: field.default for name, field in config_class.model_fields.items()}
config_fields = {name: {"default": field.default,
"type": field.annotation,
"required": field.required if hasattr(field, 'required') else False,
} for name, field in config_class.model_fields.items()}
return json.loads(json.dumps(config_fields, default=str))

@router.post("/{controller_type}/{controller_name}/config/validate")
async def validate_controller_config(controller_type: ControllerType, controller_name: str, config: Dict):
"""
Validate controller configuration against the controller's config class.

Args:
controller_type: Type of the controller
controller_name: Name of the controller
config: Configuration dictionary to validate

Returns:
Success message if configuration is valid

Raises:
HTTPException: 400 if validation fails
"""
config_class = fs_util.load_controller_config_class(controller_type.value, controller_name)
if config_class is None:
raise HTTPException(
status_code=404,
detail=f"Controller configuration class for '{controller_name}' not found"
)

try:
config_class(**config) # Validate by instantiating the model
return {"message": "Configuration is valid"}
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))


# Bot-specific controller config endpoints
Expand Down
8 changes: 4 additions & 4 deletions services/accounts_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ async def update_account_state(self):
self.accounts_state[account_name] = {}
for connector_name, connector in connectors.items():
try:
tokens_info = await self._get_connector_tokens_info(connector, connector_name, self.market_data_feed_manager)
tokens_info = await self._get_connector_tokens_info(connector, connector_name)
self.accounts_state[account_name][connector_name] = tokens_info
except Exception as e:
logger.error(f"Error updating balances for connector {connector_name} in account {account_name}: {e}")
self.accounts_state[account_name][connector_name] = []

async def _get_connector_tokens_info(self, connector, connector_name: str, market_data_manager: Optional[MarketDataFeedManager] = None) -> List[Dict]:
async def _get_connector_tokens_info(self, connector, connector_name: str) -> List[Dict]:
"""Get token info from a connector instance using cached prices when available."""
balances = [{"token": key, "units": value} for key, value in connector.get_all_balances().items() if
value != Decimal("0") and key not in settings.banned_tokens]
Expand All @@ -269,10 +269,10 @@ async def _get_connector_tokens_info(self, connector, connector_name: str, marke
prices_from_cache = {}
trading_pairs_need_update = []

if market_data_manager:
if self.market_data_feed_manager:
for trading_pair in trading_pairs:
try:
cached_price = market_data_manager.market_data_provider.get_rate(trading_pair)
cached_price = self.market_data_feed_manager.market_data_provider.get_rate(trading_pair)
if cached_price > 0:
prices_from_cache[trading_pair] = cached_price
else:
Expand Down