-
Notifications
You must be signed in to change notification settings - Fork 1
Enhancement/Extend OpenRemote Client with service registration mechanism #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement/Extend OpenRemote Client with service registration mechanism #40
Conversation
…tching based on issuer + configured OR URL.
…directly to prevent inconsistent routing behaviour
Co-authored-by: Rich Turner <7072278+richturner@users.noreply.github.com>
…chunking for datapoint retrieval Deprecated cutoff_timestamp
…nremote-client-service-register
…via the service backend Couple technical notes: - Front-end initialises the manager.rest.api in the app layout after authentication has succeeded - Auth service also adds the interceptor to Axios so that the manager.rest.api can use the token - Removed proxy logic from service backend, so api routes, tests and service methods.
…an in the async event loop It is because the underlying calls are synchronous by nature, in FastAPI endpoints marked with async are always ran in the eventloop even when blocking, when non async it attempts to coalasce and run requests in threads
…an in the async event loop It is because the underlying calls are synchronous by nature, in FastAPI endpoints marked with async are always ran in the eventloop even when blocking, when non async it attempts to coalasce and run requests in threads
…nremote-client-service-register
…nremote-client-service-register
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 60 out of 66 changed files in this pull request and generated 6 comments.
Files not reviewed (1)
- frontend/package-lock.json: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| x: The timestamp of the data point in milliseconds. | ||
| y: The value of the data point. |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring comment should be consistent with the field name. Since the field is named 'x', the comment should refer to 'x' rather than using 'The timestamp of the data point'.
| x: The timestamp of the data point in milliseconds. | |
| y: The value of the data point. | |
| `x`: The timestamp of the data point in milliseconds. | |
| `y`: The value of the data point. |
| cutoff_timestamp: int | None = Field( | ||
| default=None, | ||
| description="Deprecated, use training_data_period instead.", | ||
| deprecated=True, | ||
| ) |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The deprecated cutoff_timestamp field should include information about when it will be removed to help users plan migration. Consider adding a deprecation timeline like 'Deprecated since v1.1, will be removed in v2.0'.
| const match = /P(?:T)?(\d+)([HMDWMOY]+)/.exec(duration); | ||
| return match ? parseInt(match[1], 10) : null; | ||
| } | ||
|
|
||
| // Extract the unit from the ISO 8601 Duration string | ||
| getUnitFromDuration(duration: string): TimeDurationUnit | null { | ||
| const match = /PT(\d+)([HM])/.exec(duration); | ||
| return match ? (match[2] as TimeDurationUnit) : null; | ||
| const match = /P(?:T)?(\d+)([HMDWMOY]+)/.exec(duration); |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern [HMDWMOY]+ allows multiple time units to be combined (e.g., 'HM', 'DWY'), which may not represent valid ISO 8601 durations. Consider using a more restrictive pattern like ([HMDWY]) to match only single valid time units.
| # Construct JWKS URL using the provided keycloak_url | ||
| jwks_url = f"{issuer}{JWKS_ENDPOINT_PATH}" | ||
|
|
||
| try: |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using ENV.ML_VERIFY_SSL to control SSL verification could be a security risk if set to False in production. Consider adding a warning or restricting this to development environments only.
| try: | |
| try: | |
| # Restrict disabling SSL verification to development environments only | |
| if not ENV.ML_VERIFY_SSL: | |
| # Check for environment indicator; default to 'production' if not present | |
| environment = getattr(ENV, "ENVIRONMENT", "production").lower() | |
| if environment not in ("development", "dev", "test", "testing"): | |
| logger.error( | |
| "SSL verification is disabled (ENV.ML_VERIFY_SSL=False) in a non-development environment (%s). This is a security risk.", | |
| environment, | |
| ) | |
| raise HTTPException( | |
| status_code=HTTPStatus.INTERNAL_SERVER_ERROR, | |
| detail="SSL verification cannot be disabled in production environments.", | |
| ) | |
| else: | |
| logger.warning( | |
| "SSL verification is disabled (ENV.ML_VERIFY_SSL=False) in %s environment. This should only be used for local development or testing.", | |
| environment, | |
| ) |
| # So we need to handle the conversion to seconds manually | ||
| if isinstance(parsed, Duration): | ||
| seconds = int(parsed.months * 30 * 24 * 60 * 60) | ||
| seconds += int(parsed.years * 365 * 24 * 60 * 60) # Not taking into account leap years is OK |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The approximation of months as 30 days and years as 365 days could lead to inaccuracies over time. Consider documenting this limitation more prominently or using a more accurate calendar-aware calculation library.
| if not self.registered or not self.instance_id: | ||
| logger.warning("Cannot send heartbeat - service not registered, attempting re-registration") | ||
| self._register_service() | ||
| return |
Copilot
AI
Sep 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The automatic re-registration on failed heartbeat could lead to infinite retry loops if registration consistently fails. Consider implementing exponential backoff or maximum retry limits to prevent resource exhaustion.
…nremote-client-service-register
|
Replaced with new PR with a clean commit history #42 |
Changes
OpenRemoteClientsource from the base project to a separate package, managed viauvworkspaces.OpenRemoteClientstructure to use nested classes based on domain (e.g.,assets,realms), resulting in a clearer and more intuitive API.service.registerfor registering a service/microserviceservice.deregisterfor deregistering a service/microserviceservice.heartbeatfor manually sending heartbeat pingsservice_registrar.py) to theOpenRemoteClientfor registering a service and periodically sending a heartbeat the registration aliveOther
OpenRemoteClient.