Skip to content
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

[BUG]: error 500 for GET /pvforecast #240

Closed
gezuppe opened this issue Dec 13, 2024 · 5 comments
Closed

[BUG]: error 500 for GET /pvforecast #240

gezuppe opened this issue Dec 13, 2024 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@gezuppe
Copy link

gezuppe commented Dec 13, 2024

Describe the issue:

Running EOS in Docker on a Mac:
Request GET http://localhost:8503/pvforecast?url=https://api...
Resultes in a 500

Possible solution:
if I add the following to the docker compose file it works:

services:
  eos:
  ...
    environment:
      - TMP=/opt/eos/cache

Reproduceable code example:

if I add the following to the docker compose file it works:
services:
  eos:
  ...
    environment:
      - TMP=/opt/eos/cache

Error message:

...
HTTP/1.1" 500 Internal Server Error
eos-1  | ERROR:    Exception in ASGI application
eos-1  | Traceback (most recent call last):
eos-1  |   File "/usr/local/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
eos-1  |     result = await app(  # type: ignore[func-returns-value]
eos-1  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
eos-1  |     return await self.app(scope, receive, send)
eos-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
eos-1  |     await super().__call__(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
eos-1  |     await self.middleware_stack(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __call__
eos-1  |     raise exc
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __call__
eos-1  |     await self.app(scope, receive, _send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
eos-1  |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
eos-1  |     raise exc
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
eos-1  |     await app(scope, receive, sender)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
eos-1  |     await self.middleware_stack(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
eos-1  |     await route.handle(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
eos-1  |     await self.app(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
eos-1  |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
eos-1  |     raise exc
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
eos-1  |     await app(scope, receive, sender)
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
eos-1  |     response = await f(request)
eos-1  |                ^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 301, in app
eos-1  |     raw_response = await run_endpoint_function(
eos-1  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/fastapi/routing.py", line 214, in run_endpoint_function
eos-1  |     return await run_in_threadpool(dependant.call, **values)
eos-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/starlette/concurrency.py", line 39, in run_in_threadpool
eos-1  |     return await anyio.to_thread.run_sync(func, *args)
eos-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/anyio/to_thread.py", line 56, in run_sync
eos-1  |     return await get_async_backend().run_sync_in_worker_thread(
eos-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 2505, in run_sync_in_worker_thread
eos-1  |     return await future
eos-1  |            ^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/site-packages/anyio/_backends/_asyncio.py", line 1005, in run
eos-1  |     result = context.run(func, *args)
eos-1  |              ^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/opt/eos/akkudoktoreos/server/fastapi_server.py", line 175, in fastapi_pvprognose
eos-1  |     PVforecast = PVForecast(
eos-1  |                  ^^^^^^^^^^^
eos-1  |   File "/opt/eos/akkudoktoreos/prediction/pv_forecast.py", line 269, in __init__
eos-1  |     self.process_data(
eos-1  |   File "/opt/eos/akkudoktoreos/prediction/pv_forecast.py", line 355, in process_data
eos-1  |     data = self.load_data_from_url_with_caching(url)
eos-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/opt/eos/akkudoktoreos/utils/cachefilestore.py", line 623, in wrapper
eos-1  |     cache_file = CacheFileStore().create(
eos-1  |                  ^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/opt/eos/akkudoktoreos/utils/cachefilestore.py", line 285, in create
eos-1  |     cache_file_obj = tempfile.NamedTemporaryFile(
eos-1  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/tempfile.py", line 564, in NamedTemporaryFile
eos-1  |     prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir)
eos-1  |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/tempfile.py", line 126, in _sanitize_params
eos-1  |     dir = gettempdir()
eos-1  |           ^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/tempfile.py", line 315, in gettempdir
eos-1  |     return _os.fsdecode(_gettempdir())
eos-1  |                         ^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/tempfile.py", line 308, in _gettempdir
eos-1  |     tempdir = _get_default_tempdir()
eos-1  |               ^^^^^^^^^^^^^^^^^^^^^^
eos-1  |   File "/usr/local/lib/python3.12/tempfile.py", line 223, in _get_default_tempdir
eos-1  |     raise FileNotFoundError(_errno.ENOENT,
eos-1  | FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/opt/eos']
Gracefully stopping... (press Ctrl+C again to force)

Version information:

main branch as of today 13.12.2024

@gezuppe gezuppe added the bug Something isn't working label Dec 13, 2024
@gezuppe gezuppe changed the title [BUG]: ... [BUG]: error 500 for GET /pvforecast Dec 13, 2024
@Lasall
Copy link
Collaborator

Lasall commented Dec 13, 2024

Thank you for reporting this bug! Once the currently pending big config change #220 gets merged, we can just set the cache directory in cachefilestore by accessing the global config object.

@b0661
Copy link
Collaborator

b0661 commented Dec 14, 2024

From the failure message you can see that Python does not find a suitable directory for tempfiles. Neither the "standard" directories nor the current working directory '/opt/eos' seems to work.

FileNotFoundError: [Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/opt/eos']

The reason for the error maybe manifold. The directories might not exist, are not writable, or just do not have enough space left. As you can redirect Python to '/opt/eos/cache' it seems '/opt/eos' is not writable but '/opt/eos/cache' is.

Your change is a work around, but it would be interesting to get the root cause. Either the docker image on Mac or the Mac setup itself.

I do not have a Mac. Maybe you can check the system setup to have a valid directory for tempfiles.

@gezuppe
Copy link
Author

gezuppe commented Dec 14, 2024

@b0661 I played around a bit:
It is related to the read_only flag in the docker_compose file.
I assume we don't want a writable file system so I ended up with creating a tmpfs volume at /tmp/eos and point python to it with the mentioned ENV variable:

...
    environment:
      - TMP=/tmp/eos
...
...
    volumes:
      - type: tmpfs
        target: /tmp/eos
...

@b0661
Copy link
Collaborator

b0661 commented Dec 15, 2024

@gezuppe, if you just mount the tmpfs volume to /tmp (instead of /tmp/eos) the environment variable should not be necessary.

@Lasall Lasall self-assigned this Dec 15, 2024
Lasall added a commit to Lasall/EOS that referenced this issue Dec 17, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes Akkudoktor-EOS#240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
Lasall added a commit to Lasall/EOS that referenced this issue Dec 19, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes Akkudoktor-EOS#240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
Lasall added a commit to Lasall/EOS that referenced this issue Dec 27, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes Akkudoktor-EOS#240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
Lasall added a commit to Lasall/EOS that referenced this issue Dec 30, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes Akkudoktor-EOS#240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
Lasall added a commit to Lasall/EOS that referenced this issue Dec 30, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes Akkudoktor-EOS#240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
Lasall added a commit that referenced this issue Dec 30, 2024
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
drbacke pushed a commit that referenced this issue Jan 1, 2025
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
Lasall added a commit that referenced this issue Jan 1, 2025
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
Lasall added a commit that referenced this issue Jan 1, 2025
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
Lasall added a commit that referenced this issue Jan 2, 2025
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
Lasall added a commit that referenced this issue Jan 2, 2025
 * Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or
   absolute path).
    - config_folder_path read-only
    - config_file_path read-only
 * Default values to support app start with empty config:
    - latitude/longitude (Berlin)
    - optimization_ev_available_charge_rates_percent (null, so model
      default value is used)
    - Enable Akkudoktor electricity price forecast (docker-compose).
 * Fix some endpoints (empty data, remove unused params, fix types).
 * cacheutil: Use cache dir. Closes #240
 * Support EOS_LOGGING_LEVEL environment variable to set log level.
 * tests: All tests use separate temporary config
    - Add pytest switch --check-config-side-effect to check user
      config file existence after each test. Will also fail if user config
      existed before test execution (but will only check after the test has
      run).
      Enable flag in github workflow.
    - Globally mock platformdirs in config module. Now no longer required
      to patch individually.
      Function calls to config instance (e.g. merge_settings_from_dict)
      were unaffected previously.
 * Set Berlin as default location (default config/docker-compose).
@Lasall
Copy link
Collaborator

Lasall commented Jan 7, 2025

Fixed in #318 (main) and #257 (feature)

@Lasall Lasall closed this as completed Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants