-
Notifications
You must be signed in to change notification settings - Fork 43
Fix env config to variables #1790
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
base: main
Are you sure you want to change the base?
Conversation
avilches
left a comment
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.
Finally, not sure if creating one single PR for the gateway and the client, which are two completely separate projects in the same repo, is the best idea. It makes the PRs unnecessary larger. Just to be clear, I'm not asking you to make another PR for the client, I'm just mentioning it for the next ones...
gateway/constants.py
Outdated
| """Constants for environment variable names.""" | ||
|
|
||
| # Version and Debug | ||
| VERSION = "VERSION" | ||
| DEBUG = "DEBUG" | ||
|
|
||
| # Security | ||
| DJANGO_SECRET_KEY = "DJANGO_SECRET_KEY" | ||
| ALLOWED_HOSTS = "ALLOWED_HOSTS" | ||
| CSRF_TRUSTED_ORIGINS = "CSRF_TRUSTED_ORIGINS" | ||
| CORS_ALLOWED_ORIGIN_REGEXES = "CORS_ALLOWED_ORIGIN_REGEXES" | ||
|
|
||
| # Database | ||
| DATABASE_NAME = "DATABASE_NAME" | ||
| DATABASE_USER = "DATABASE_USER" | ||
| DATABASE_PASSWORD = "DATABASE_PASSWORD" | ||
| DATABASE_HOST = "DATABASE_HOST" | ||
| DATABASE_PORT = "DATABASE_PORT" | ||
|
|
||
| # Authentication | ||
| SETTINGS_AUTH_MECHANISM = "SETTINGS_AUTH_MECHANISM" | ||
| SETTINGS_AUTH_MOCK_TOKEN = "SETTINGS_AUTH_MOCK_TOKEN" | ||
| SETTINGS_AUTH_MOCKPROVIDER_REGISTRY = "SETTINGS_AUTH_MOCKPROVIDER_REGISTRY" | ||
| QUANTUM_PLATFORM_API_BASE_URL = "QUANTUM_PLATFORM_API_BASE_URL" | ||
| SETTINGS_TOKEN_AUTH_VERIFICATION_FIELD = "SETTINGS_TOKEN_AUTH_VERIFICATION_FIELD" | ||
|
|
||
| # Site | ||
| SITE_HOST = "SITE_HOST" | ||
|
|
||
| # Resource Limits | ||
| LIMITS_JOBS_PER_USER = "LIMITS_JOBS_PER_USER" | ||
| LIMITS_MAX_CLUSTERS = "LIMITS_MAX_CLUSTERS" | ||
| LIMITS_MAX_GPU_CLUSTERS = "LIMITS_MAX_GPU_CLUSTERS" | ||
| LIMITS_CPU_PER_TASK = "LIMITS_CPU_PER_TASK" | ||
| LIMITS_GPU_PER_TASK = "LIMITS_GPU_PER_TASK" | ||
| LIMITS_MEMORY_PER_TASK = "LIMITS_MEMORY_PER_TASK" | ||
| MAINTENANCE = "MAINTENANCE" | ||
|
|
||
| # Ray Cluster Configuration | ||
| RAY_KUBERAY_NAMESPACE = "RAY_KUBERAY_NAMESPACE" | ||
| RAY_CLUSTER_MODE_LOCAL = "RAY_CLUSTER_MODE_LOCAL" | ||
| RAY_CLUSTER_MODE_LOCAL_HOST = "RAY_CLUSTER_MODE_LOCAL_HOST" | ||
| RAY_NODE_IMAGE = "RAY_NODE_IMAGE" | ||
| RAY_CLUSTER_WORKER_REPLICAS = "RAY_CLUSTER_WORKER_REPLICAS" | ||
| RAY_CLUSTER_WORKER_REPLICAS_MAX = "RAY_CLUSTER_WORKER_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS = "RAY_CLUSTER_WORKER_MIN_REPLICAS" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX = "RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS = "RAY_CLUSTER_WORKER_MAX_REPLICAS" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX = "RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_AUTO_SCALING = "RAY_CLUSTER_WORKER_AUTO_SCALING" | ||
| RAY_CLUSTER_MAX_READINESS_TIME = "RAY_CLUSTER_MAX_READINESS_TIME" | ||
| RAY_SETUP_MAX_RETRIES = "RAY_SETUP_MAX_RETRIES" | ||
| RAY_CLUSTER_NO_DELETE_ON_COMPLETE = "RAY_CLUSTER_NO_DELETE_ON_COMPLETE" | ||
| RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL = "RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL" | ||
| RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL = "RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL" | ||
|
|
||
| # Program Configuration | ||
| PROGRAM_TIMEOUT = "PROGRAM_TIMEOUT" | ||
| GATEWAY_ALLOWLIST_CONFIG = "GATEWAY_ALLOWLIST_CONFIG" | ||
| GATEWAY_GPU_JOBS_CONFIG = "GATEWAY_GPU_JOBS_CONFIG" | ||
| GATEWAY_DYNAMIC_DEPENDENCIES = "GATEWAY_DYNAMIC_DEPENDENCIES" | ||
|
|
||
| # IBM Cloud and Qiskit | ||
| QISKIT_IBM_URL = "QISKIT_IBM_URL" | ||
| IQP_QCON_API_BASE_URL = "IQP_QCON_API_BASE_URL" | ||
| IAM_IBM_CLOUD_BASE_URL = "IAM_IBM_CLOUD_BASE_URL" | ||
| RESOURCE_CONTROLLER_IBM_CLOUD_BASE_URL = "RESOURCE_CONTROLLER_IBM_CLOUD_BASE_URL" | ||
| RESOURCE_PLANS_ID_ALLOWED = "RESOURCE_PLANS_ID_ALLOWED" | ||
|
|
||
| # Custom Image | ||
| CUSTOM_IMAGE_PACKAGE_NAME = "CUSTOM_IMAGE_PACKAGE_NAME" | ||
| CUSTOM_IMAGE_PACKAGE_PATH = "CUSTOM_IMAGE_PACKAGE_PATH" | ||
|
|
||
| # Functions | ||
| FUNCTIONS_LOGS_SIZE_LIMIT = "FUNCTIONS_LOGS_SIZE_LIMIT" | ||
|
|
||
| # OpenTelemetry | ||
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" | ||
| OTEL_EXPORTER_OTLP_TRACES_INSECURE = "OTEL_EXPORTER_OTLP_TRACES_INSECURE" | ||
| OTEL_ENABLED = "OTEL_ENABLED" | ||
|
|
||
| # Default values | ||
| VERSION_DEFAULT = "UNKNOWN" | ||
| DEBUG_DEFAULT = "1" | ||
| DJANGO_SECRET_KEY_DEFAULT = ( | ||
| "django-insecure-&)i3b5aue*#-i6k9i-03qm(d!0h&662lbhj12on_*gimn3x8p7" | ||
| ) | ||
| ALLOWED_HOSTS_DEFAULT = "*" | ||
| CSRF_TRUSTED_ORIGINS_DEFAULT = "http://localhost" | ||
| CORS_ALLOWED_ORIGIN_REGEXES_DEFAULT = "http://localhost" | ||
| DATABASE_NAME_DEFAULT = "serverlessdb" | ||
| DATABASE_USER_DEFAULT = "serverlessuser" | ||
| DATABASE_PASSWORD_DEFAULT = "serverlesspassword" | ||
| DATABASE_HOST_DEFAULT = "localhost" | ||
| DATABASE_PORT_DEFAULT = "5432" | ||
| SETTINGS_AUTH_MECHANISM_DEFAULT = "default" | ||
| SETTINGS_AUTH_MOCK_TOKEN_DEFAULT = "awesome_token" | ||
| SITE_HOST_DEFAULT = "http://localhost:8000" | ||
| LIMITS_JOBS_PER_USER_DEFAULT = "2" | ||
| LIMITS_MAX_CLUSTERS_DEFAULT = "6" | ||
| LIMITS_MAX_GPU_CLUSTERS_DEFAULT = "1" | ||
| LIMITS_CPU_PER_TASK_DEFAULT = "4" | ||
| LIMITS_GPU_PER_TASK_DEFAULT = "1" | ||
| LIMITS_MEMORY_PER_TASK_DEFAULT = "8" | ||
| RAY_KUBERAY_NAMESPACE_DEFAULT = "qiskit-serverless" | ||
| RAY_CLUSTER_MODE_LOCAL_DEFAULT = "0" | ||
| RAY_CLUSTER_MODE_LOCAL_HOST_DEFAULT = "http://localhost:8265" | ||
| RAY_NODE_IMAGE_DEFAULT = "icr.io/quantum-public/qiskit-serverless/ray-node:0.27.1" | ||
| RAY_CLUSTER_WORKER_REPLICAS_DEFAULT = "1" | ||
| RAY_CLUSTER_WORKER_REPLICAS_MAX_DEFAULT = "5" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_DEFAULT = "1" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX_DEFAULT = "2" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_DEFAULT = "4" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX_DEFAULT = "10" | ||
| RAY_CLUSTER_MAX_READINESS_TIME_DEFAULT = "120" | ||
| RAY_SETUP_MAX_RETRIES_DEFAULT = "30" | ||
| RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL_DEFAULT = ( | ||
| "ibm-cloud.kubernetes.io/worker-pool-name: default" | ||
| ) | ||
| RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL_DEFAULT = ( | ||
| "ibm-cloud.kubernetes.io/worker-pool-name: gpu-workers" | ||
| ) | ||
| PROGRAM_TIMEOUT_DEFAULT = "14" | ||
| GATEWAY_ALLOWLIST_CONFIG_DEFAULT = "api/v1/allowlist.json" | ||
| GATEWAY_GPU_JOBS_CONFIG_DEFAULT = "api/v1/gpu-jobs.json" | ||
| GATEWAY_DYNAMIC_DEPENDENCIES_DEFAULT = "requirements-dynamic-dependencies.txt" | ||
| QISKIT_IBM_URL_DEFAULT = "https://cloud.ibm.com" | ||
| CUSTOM_IMAGE_PACKAGE_NAME_DEFAULT = "runner" | ||
| CUSTOM_IMAGE_PACKAGE_PATH_DEFAULT = "/runner" | ||
| FUNCTIONS_LOGS_SIZE_LIMIT_DEFAULT = "50" | ||
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT_DEFAULT = "http://otel-collector:4317" | ||
| OTEL_EXPORTER_OTLP_TRACES_INSECURE_DEFAULT = "0" | ||
| OTEL_ENABLED_DEFAULT = "0" |
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.
Do we really want this kind of file now, when we are using a Config class which is the only place that's actually using these constants? I mean, it makes sense to have all these constants and their defaults if we are going to use os.environ.get() calls anywhere in our code, so that if a variable name changes or a default is changed, we only have to do it in one place (the constant.py file). But if all accesses to these variables are made from Config, which is the new source of truth, what's the point of adding this level of indirection? I would just hardcode both the variables and the defaults within each method. That way, it's the only place where these values are hardcoded, and it's easier to see and modify.
gateway/constants.py
Outdated
| """Constants for environment variable names.""" | ||
|
|
||
| # Version and Debug | ||
| VERSION = "VERSION" | ||
| DEBUG = "DEBUG" | ||
|
|
||
| # Security | ||
| DJANGO_SECRET_KEY = "DJANGO_SECRET_KEY" | ||
| ALLOWED_HOSTS = "ALLOWED_HOSTS" | ||
| CSRF_TRUSTED_ORIGINS = "CSRF_TRUSTED_ORIGINS" | ||
| CORS_ALLOWED_ORIGIN_REGEXES = "CORS_ALLOWED_ORIGIN_REGEXES" | ||
|
|
||
| # Database | ||
| DATABASE_NAME = "DATABASE_NAME" | ||
| DATABASE_USER = "DATABASE_USER" | ||
| DATABASE_PASSWORD = "DATABASE_PASSWORD" | ||
| DATABASE_HOST = "DATABASE_HOST" | ||
| DATABASE_PORT = "DATABASE_PORT" | ||
|
|
||
| # Authentication | ||
| SETTINGS_AUTH_MECHANISM = "SETTINGS_AUTH_MECHANISM" | ||
| SETTINGS_AUTH_MOCK_TOKEN = "SETTINGS_AUTH_MOCK_TOKEN" | ||
| SETTINGS_AUTH_MOCKPROVIDER_REGISTRY = "SETTINGS_AUTH_MOCKPROVIDER_REGISTRY" | ||
| QUANTUM_PLATFORM_API_BASE_URL = "QUANTUM_PLATFORM_API_BASE_URL" | ||
| SETTINGS_TOKEN_AUTH_VERIFICATION_FIELD = "SETTINGS_TOKEN_AUTH_VERIFICATION_FIELD" | ||
|
|
||
| # Site | ||
| SITE_HOST = "SITE_HOST" | ||
|
|
||
| # Resource Limits | ||
| LIMITS_JOBS_PER_USER = "LIMITS_JOBS_PER_USER" | ||
| LIMITS_MAX_CLUSTERS = "LIMITS_MAX_CLUSTERS" | ||
| LIMITS_MAX_GPU_CLUSTERS = "LIMITS_MAX_GPU_CLUSTERS" | ||
| LIMITS_CPU_PER_TASK = "LIMITS_CPU_PER_TASK" | ||
| LIMITS_GPU_PER_TASK = "LIMITS_GPU_PER_TASK" | ||
| LIMITS_MEMORY_PER_TASK = "LIMITS_MEMORY_PER_TASK" | ||
| MAINTENANCE = "MAINTENANCE" | ||
|
|
||
| # Ray Cluster Configuration | ||
| RAY_KUBERAY_NAMESPACE = "RAY_KUBERAY_NAMESPACE" | ||
| RAY_CLUSTER_MODE_LOCAL = "RAY_CLUSTER_MODE_LOCAL" | ||
| RAY_CLUSTER_MODE_LOCAL_HOST = "RAY_CLUSTER_MODE_LOCAL_HOST" | ||
| RAY_NODE_IMAGE = "RAY_NODE_IMAGE" | ||
| RAY_CLUSTER_WORKER_REPLICAS = "RAY_CLUSTER_WORKER_REPLICAS" | ||
| RAY_CLUSTER_WORKER_REPLICAS_MAX = "RAY_CLUSTER_WORKER_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS = "RAY_CLUSTER_WORKER_MIN_REPLICAS" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX = "RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS = "RAY_CLUSTER_WORKER_MAX_REPLICAS" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX = "RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX" | ||
| RAY_CLUSTER_WORKER_AUTO_SCALING = "RAY_CLUSTER_WORKER_AUTO_SCALING" | ||
| RAY_CLUSTER_MAX_READINESS_TIME = "RAY_CLUSTER_MAX_READINESS_TIME" | ||
| RAY_SETUP_MAX_RETRIES = "RAY_SETUP_MAX_RETRIES" | ||
| RAY_CLUSTER_NO_DELETE_ON_COMPLETE = "RAY_CLUSTER_NO_DELETE_ON_COMPLETE" | ||
| RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL = "RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL" | ||
| RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL = "RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL" | ||
|
|
||
| # Program Configuration | ||
| PROGRAM_TIMEOUT = "PROGRAM_TIMEOUT" | ||
| GATEWAY_ALLOWLIST_CONFIG = "GATEWAY_ALLOWLIST_CONFIG" | ||
| GATEWAY_GPU_JOBS_CONFIG = "GATEWAY_GPU_JOBS_CONFIG" | ||
| GATEWAY_DYNAMIC_DEPENDENCIES = "GATEWAY_DYNAMIC_DEPENDENCIES" | ||
|
|
||
| # IBM Cloud and Qiskit | ||
| QISKIT_IBM_URL = "QISKIT_IBM_URL" | ||
| IQP_QCON_API_BASE_URL = "IQP_QCON_API_BASE_URL" | ||
| IAM_IBM_CLOUD_BASE_URL = "IAM_IBM_CLOUD_BASE_URL" | ||
| RESOURCE_CONTROLLER_IBM_CLOUD_BASE_URL = "RESOURCE_CONTROLLER_IBM_CLOUD_BASE_URL" | ||
| RESOURCE_PLANS_ID_ALLOWED = "RESOURCE_PLANS_ID_ALLOWED" | ||
|
|
||
| # Custom Image | ||
| CUSTOM_IMAGE_PACKAGE_NAME = "CUSTOM_IMAGE_PACKAGE_NAME" | ||
| CUSTOM_IMAGE_PACKAGE_PATH = "CUSTOM_IMAGE_PACKAGE_PATH" | ||
|
|
||
| # Functions | ||
| FUNCTIONS_LOGS_SIZE_LIMIT = "FUNCTIONS_LOGS_SIZE_LIMIT" | ||
|
|
||
| # OpenTelemetry | ||
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT" | ||
| OTEL_EXPORTER_OTLP_TRACES_INSECURE = "OTEL_EXPORTER_OTLP_TRACES_INSECURE" | ||
| OTEL_ENABLED = "OTEL_ENABLED" | ||
|
|
||
| # Default values | ||
| VERSION_DEFAULT = "UNKNOWN" | ||
| DEBUG_DEFAULT = "1" | ||
| DJANGO_SECRET_KEY_DEFAULT = ( | ||
| "django-insecure-&)i3b5aue*#-i6k9i-03qm(d!0h&662lbhj12on_*gimn3x8p7" | ||
| ) | ||
| ALLOWED_HOSTS_DEFAULT = "*" | ||
| CSRF_TRUSTED_ORIGINS_DEFAULT = "http://localhost" | ||
| CORS_ALLOWED_ORIGIN_REGEXES_DEFAULT = "http://localhost" | ||
| DATABASE_NAME_DEFAULT = "serverlessdb" | ||
| DATABASE_USER_DEFAULT = "serverlessuser" | ||
| DATABASE_PASSWORD_DEFAULT = "serverlesspassword" | ||
| DATABASE_HOST_DEFAULT = "localhost" | ||
| DATABASE_PORT_DEFAULT = "5432" | ||
| SETTINGS_AUTH_MECHANISM_DEFAULT = "default" | ||
| SETTINGS_AUTH_MOCK_TOKEN_DEFAULT = "awesome_token" | ||
| SITE_HOST_DEFAULT = "http://localhost:8000" | ||
| LIMITS_JOBS_PER_USER_DEFAULT = "2" | ||
| LIMITS_MAX_CLUSTERS_DEFAULT = "6" | ||
| LIMITS_MAX_GPU_CLUSTERS_DEFAULT = "1" | ||
| LIMITS_CPU_PER_TASK_DEFAULT = "4" | ||
| LIMITS_GPU_PER_TASK_DEFAULT = "1" | ||
| LIMITS_MEMORY_PER_TASK_DEFAULT = "8" | ||
| RAY_KUBERAY_NAMESPACE_DEFAULT = "qiskit-serverless" | ||
| RAY_CLUSTER_MODE_LOCAL_DEFAULT = "0" | ||
| RAY_CLUSTER_MODE_LOCAL_HOST_DEFAULT = "http://localhost:8265" | ||
| RAY_NODE_IMAGE_DEFAULT = "icr.io/quantum-public/qiskit-serverless/ray-node:0.27.1" | ||
| RAY_CLUSTER_WORKER_REPLICAS_DEFAULT = "1" | ||
| RAY_CLUSTER_WORKER_REPLICAS_MAX_DEFAULT = "5" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_DEFAULT = "1" | ||
| RAY_CLUSTER_WORKER_MIN_REPLICAS_MAX_DEFAULT = "2" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_DEFAULT = "4" | ||
| RAY_CLUSTER_WORKER_MAX_REPLICAS_MAX_DEFAULT = "10" | ||
| RAY_CLUSTER_MAX_READINESS_TIME_DEFAULT = "120" | ||
| RAY_SETUP_MAX_RETRIES_DEFAULT = "30" | ||
| RAY_CLUSTER_CPU_NODE_SELECTOR_LABEL_DEFAULT = ( | ||
| "ibm-cloud.kubernetes.io/worker-pool-name: default" | ||
| ) | ||
| RAY_CLUSTER_GPU_NODE_SELECTOR_LABEL_DEFAULT = ( | ||
| "ibm-cloud.kubernetes.io/worker-pool-name: gpu-workers" | ||
| ) | ||
| PROGRAM_TIMEOUT_DEFAULT = "14" | ||
| GATEWAY_ALLOWLIST_CONFIG_DEFAULT = "api/v1/allowlist.json" | ||
| GATEWAY_GPU_JOBS_CONFIG_DEFAULT = "api/v1/gpu-jobs.json" | ||
| GATEWAY_DYNAMIC_DEPENDENCIES_DEFAULT = "requirements-dynamic-dependencies.txt" | ||
| QISKIT_IBM_URL_DEFAULT = "https://cloud.ibm.com" | ||
| CUSTOM_IMAGE_PACKAGE_NAME_DEFAULT = "runner" | ||
| CUSTOM_IMAGE_PACKAGE_PATH_DEFAULT = "/runner" | ||
| FUNCTIONS_LOGS_SIZE_LIMIT_DEFAULT = "50" | ||
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT_DEFAULT = "http://otel-collector:4317" | ||
| OTEL_EXPORTER_OTLP_TRACES_INSECURE_DEFAULT = "0" | ||
| OTEL_ENABLED_DEFAULT = "0" |
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 same approach with the settings.py class, why do we create a Config class when we only use it once during bootstrap to assign its values to a bunch of constants that need to be imported? I would remove the settings.py and only use the new Config class, which should be the de facto source of truth for the config/settings (config = settings, right?).
|
In fact, if I remember correctly the proposal was done by @korgan00 but only for the client. I think Django is just managing this correctly. I wouldn't change the gateway. |
|
I proposed this for client but the reasons also apply for gateway I think. The main reason is not access to envars anywhere in the code having a default value in each call and unify everything in one class or somewhere, I dont know if there is a django way to improve this. |
|
But you access to the env_vars only in the settings.py. Through the code you use: from django.conf import settings
....
settings.LIMITS_JOBS_PER_USERI don't think there is nothing wrong with this approach. Or I don't think so at least. This is what we were trying to fix in the client: https://github.com/Qiskit/qiskit-serverless/pull/1790/files#diff-fdc3aef5e1a595990db1b71f1ca195cbdfc589291d1f23c213c5fe735c8b0611L127 |
The main goal of the issue is to define a single source of truth (settings, Config, or whatever) instead of reading environment variables scattered throughout the codebase. To achieve this, I'm fine with having a settings.py CUSTOM_IMAGE_PACKAGE_NAME = Config.custom_image_package_name()which calls to config.py: def custom_image_package_name(cls) -> str:
"""Get custom image package name."""
return os.environ.get(
CUSTOM_IMAGE_PACKAGE_NAME, CUSTOM_IMAGE_PACKAGE_NAME_DEFAULT
)which requires constants.py CUSTOM_IMAGE_PACKAGE_NAME = "CUSTOM_IMAGE_PACKAGE_NAME"
CUSTOM_IMAGE_PACKAGE_NAME_DEFAULT = "CUSTOM_IMAGE_PACKAGE_NAME_DEFAULT"I suggest having only settings, only Config, but no both. And remove the constants. That will make easier for us: just one single place to use and one single place to add/update variables. Regarding constants in settings vs class Config, I think class is superior because:
|
|
For the purpose of this PR as it was created focusing on the client my proposal is to create an issue for the gateway and have the final discussion there. WDYT @avilches , @korgan00 , @paaragon . I think everyone agrees at least that this PR should be simplified and contains only the changes in the |
This reverts commit 32030c8.
…t-serverless into fix-env-config-to-variables
|
Agree with @avilches . We can just remove the constants file now and use literals in the Config file. |
Ok, this is what I did: I have changed the config file to use literals instead of constants. Also, I have removed from the constants.py file all the variables that weren't being used |
…t-serverless into fix-env-config-to-variables
| @classmethod | ||
| def gateway_token(cls) -> Optional[str]: | ||
| """Get gateway provider token.""" | ||
| return os.environ.get("ENV_GATEWAY_PROVIDER_TOKEN", None) |
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.
Why was the "provider" part removed from the gateway host, token and version? I mean, why not gateway_provider_token, gateway_provider_version and gateway_provider_host instead... is the "provider" word redundant in the gateway?
| def gateway_version(cls) -> str: | ||
| """Get gateway provider version.""" | ||
| return os.environ.get("ENV_GATEWAY_PROVIDER_VERSION", "v1") | ||
|
|
||
| @classmethod | ||
| def gateway_provider_version(cls) -> str: | ||
| """Get gateway provider version (alias for gateway_version).""" | ||
| return cls.gateway_version() |
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.
Why have two methods (where one calls the other) instead of just one?
| # telemetry | ||
| OT_PROGRAM_NAME = "OT_PROGRAM_NAME" | ||
| OT_PROGRAM_NAME_DEFAULT = "unnamed_execution" | ||
| OT_JAEGER_HOST = "OT_JAEGER_HOST" | ||
| OT_JAEGER_HOST_KEY = "OT_JAEGER_HOST_KEY" | ||
| OT_JAEGER_PORT_KEY = "OT_JAEGER_PORT_KEY" | ||
| OT_TRACEPARENT_ID_KEY = "OT_TRACEPARENT_ID_KEY" | ||
| OT_INSECURE = "OT_INSECURE" | ||
| OT_ENABLED = "OT_ENABLED" | ||
| OT_RAY_TRACER = "OT_RAY_TRACER" | ||
| OT_SPAN_DEFAULT_NAME = "entrypoint" | ||
| OT_ATTRIBUTE_PREFIX = "qs" | ||
| OT_LABEL_CALL_LOCATION = "qs.location" | ||
|
|
||
| # request timeout | ||
| REQUESTS_TIMEOUT_DEFAULT: int = 30 | ||
| REQUESTS_TIMEOUT_OVERRIDE = "REQUESTS_TIMEOUT_OVERRIDE" | ||
| REQUESTS_STREAMING_TIMEOUT_DEFAULT: int = 60 | ||
| REQUESTS_STREAMING_TIMEOUT_OVERRIDE = "REQUESTS_TIMEOUT_OVERRIDE" | ||
|
|
||
| # gateway | ||
| ENV_GATEWAY_PROVIDER_HOST = "ENV_GATEWAY_PROVIDER_HOST" | ||
| ENV_GATEWAY_PROVIDER_VERSION = "ENV_GATEWAY_PROVIDER_VERSION" | ||
| ENV_GATEWAY_PROVIDER_TOKEN = "ENV_GATEWAY_PROVIDER_TOKEN" | ||
| GATEWAY_PROVIDER_VERSION_DEFAULT = "v1" | ||
|
|
||
| # auth | ||
| ENV_JOB_GATEWAY_TOKEN = "ENV_JOB_GATEWAY_TOKEN" | ||
| ENV_JOB_GATEWAY_INSTANCE = "ENV_JOB_GATEWAY_INSTANCE" | ||
| ENV_JOB_GATEWAY_HOST = "ENV_JOB_GATEWAY_HOST" | ||
| ENV_JOB_ID_GATEWAY = "ENV_JOB_ID_GATEWAY" | ||
| ENV_JOB_ARGUMENTS = "ENV_JOB_ARGUMENTS" | ||
| QISKIT_IBM_CHANNEL = "QISKIT_IBM_CHANNEL" | ||
|
|
||
| DATA_PATH = "DATA_PATH" | ||
|
|
||
| # job | ||
| ENV_ACCESS_TRIAL = "ENV_ACCESS_TRIAL" |
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.
I think these variables should be removed too. If the codebase is still using them, then their usage should be done through the new Config class.
| @classmethod | ||
| def requests_streaming_timeout(cls) -> int: | ||
| """Get streaming request timeout in seconds.""" | ||
| return int(os.environ.get("REQUESTS_TIMEOUT_OVERRIDE", "60")) |
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.
These two config values have the same environment variable REQUESTS_TIMEOUT_OVERRIDE
|
|
||
| # IBM Serverless Configuration | ||
| @classmethod | ||
| def ibm_serverless_host_url(cls) -> str: |
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.
I should be ibm_serverless_host_url_override
| file using the default account name. | ||
| Args: | ||
| host: host of gateway. Optional. It uses IBM_SERVERLESS_HOST_URL env var or IBM host |
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.
| host: host of gateway. Optional. It uses IBM_SERVERLESS_HOST_URL_OVERRIDE env var or IBM host |
Wrong environment variable, my bad... 0294630#diff-fdc3aef5e1a595990db1b71f1ca195cbdfc589291d1f23c213c5fe735c8b0611R112
avilches
left a comment
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.
Check comments
Summary
This PR refactors the way we access to the environment variables centralizing them into one single class (one for the client and one for the gateway)
Details and comments