Skip to content

Commit

Permalink
feat: cleaner public api (#54)
Browse files Browse the repository at this point in the history
Closes #53

### Summary of Changes

Define a small public interface consisting of
* `safeds_runner.file_mtime`,
* `safeds_runner.memoized_call`,
* `safeds_runner.save_placeholder`.

These are used by the code generator of the
[DSL](https://github.com/Safe-DS/DSL).
  • Loading branch information
lars-reimann committed Feb 22, 2024
1 parent eb834fa commit 6d8dde7
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 37 deletions.
8 changes: 8 additions & 0 deletions src/safeds_runner/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
"""A runner for the Python code generated from Safe-DS programs."""

from .server._pipeline_manager import file_mtime, memoized_call, save_placeholder

__all__ = [
"file_mtime",
"memoized_call",
"save_placeholder",
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

import stack_data

from safeds_runner.server.memoization_map import MemoizationMap
from safeds_runner.server.messages import (
from ._memoization_map import MemoizationMap
from ._messages import (
Message,
MessageDataProgram,
create_placeholder_description,
Expand All @@ -26,7 +26,7 @@
message_type_runtime_error,
message_type_runtime_progress,
)
from safeds_runner.server.module_manager import InMemoryFinder
from ._module_manager import InMemoryFinder


class PipelineManager:
Expand Down Expand Up @@ -288,7 +288,7 @@ def execute(self) -> None:
current_pipeline: PipelineProcess | None = None


def runner_save_placeholder(placeholder_name: str, value: Any) -> None:
def save_placeholder(placeholder_name: str, value: Any) -> None:
"""
Save a placeholder for the current running pipeline.
Expand All @@ -303,7 +303,7 @@ def runner_save_placeholder(placeholder_name: str, value: Any) -> None:
current_pipeline.save_placeholder(placeholder_name, value)


def runner_memoized_function_call(
def memoized_call(
function_name: str,
function_callable: typing.Callable,
parameters: list[Any],
Expand Down Expand Up @@ -336,7 +336,7 @@ def runner_memoized_function_call(
return memoization_map.memoized_function_call(function_name, function_callable, parameters, hidden_parameters)


def runner_filemtime(filename: str) -> int | None:
def file_mtime(filename: str) -> int | None:
"""
Get the last modification timestamp of the provided file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@
import hypercorn.asyncio
import quart.app

from safeds_runner.server import messages
from safeds_runner.server.json_encoder import SafeDsEncoder
from safeds_runner.server.messages import (
from ._json_encoder import SafeDsEncoder
from ._messages import (
Message,
create_placeholder_value,
message_type_placeholder_value,
message_types,
parse_validate_message,
validate_placeholder_query_message_data,
validate_program_message_data,
)
from safeds_runner.server.pipeline_manager import PipelineManager
from ._pipeline_manager import PipelineManager


def create_flask_app() -> quart.app.Quart:
Expand Down Expand Up @@ -108,7 +110,7 @@ async def _ws_main_foreground(
pipeline_manager.shutdown()
sys.exit(0)
case "program":
program_data, invalid_message = messages.validate_program_message_data(received_object.data)
program_data, invalid_message = validate_program_message_data(received_object.data)
if program_data is None:
logging.error("Invalid message data specified in: %s (%s)", received_message, invalid_message)
await output_queue.put(None)
Expand All @@ -119,7 +121,7 @@ async def _ws_main_foreground(
pipeline_manager.execute_pipeline(program_data, received_object.id)
case "placeholder_query":
# For this query, a response can be directly sent to the requesting connection
placeholder_query_data, invalid_message = messages.validate_placeholder_query_message_data(
placeholder_query_data, invalid_message = validate_placeholder_query_message_data(
received_object.data,
)
if placeholder_query_data is None:
Expand Down Expand Up @@ -173,7 +175,7 @@ async def _ws_main_foreground(
),
)
case _:
if received_object.type not in messages.message_types:
if received_object.type not in message_types:
logging.warning("Invalid message type: %s", received_object.type)

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion src/safeds_runner/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import logging

from safeds_runner.server.server import SafeDsServer
from ._server import SafeDsServer


def start_server(port: int) -> None:
Expand Down
2 changes: 1 addition & 1 deletion tests/safeds_runner/server/test_json_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pytest
from safeds.data.image.containers import Image
from safeds.data.tabular.containers import Table
from safeds_runner.server.json_encoder import SafeDsEncoder
from safeds_runner.server._json_encoder import SafeDsEncoder


@pytest.mark.parametrize(
Expand Down
30 changes: 15 additions & 15 deletions tests/safeds_runner/server/test_memoization.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
from typing import Any

import pytest
from safeds_runner.server import pipeline_manager
from safeds_runner.server.memoization_map import (
from safeds_runner.server import _pipeline_manager
from safeds_runner.server._memoization_map import (
MemoizationMap,
MemoizationStats,
_convert_list_to_tuple,
_get_size_of_value,
)
from safeds_runner.server.messages import MessageDataProgram, ProgramMainInformation
from safeds_runner.server.pipeline_manager import PipelineProcess, runner_filemtime, runner_memoized_function_call
from safeds_runner.server._messages import MessageDataProgram, ProgramMainInformation
from safeds_runner.server._pipeline_manager import PipelineProcess, file_mtime, memoized_call


@pytest.mark.parametrize(
Expand All @@ -32,25 +32,25 @@ def test_memoization_already_present_values(
hidden_params: list,
expected_result: Any,
) -> None:
pipeline_manager.current_pipeline = PipelineProcess(
_pipeline_manager.current_pipeline = PipelineProcess(
MessageDataProgram({}, ProgramMainInformation("", "", "")),
"",
Queue(),
{},
MemoizationMap({}, {}),
)
pipeline_manager.current_pipeline.get_memoization_map()._map_values[(
_pipeline_manager.current_pipeline.get_memoization_map()._map_values[(
function_name,
_convert_list_to_tuple(params),
_convert_list_to_tuple(hidden_params),
)] = expected_result
pipeline_manager.current_pipeline.get_memoization_map()._map_stats[function_name] = MemoizationStats(
_pipeline_manager.current_pipeline.get_memoization_map()._map_stats[function_name] = MemoizationStats(
[time.perf_counter_ns()],
[],
[],
[sys.getsizeof(expected_result)],
)
result = pipeline_manager.runner_memoized_function_call(function_name, lambda *_: None, params, hidden_params)
result = _pipeline_manager.memoized_call(function_name, lambda *_: None, params, hidden_params)
assert result == expected_result


Expand All @@ -69,30 +69,30 @@ def test_memoization_not_present_values(
hidden_params: list,
expected_result: Any,
) -> None:
pipeline_manager.current_pipeline = PipelineProcess(
_pipeline_manager.current_pipeline = PipelineProcess(
MessageDataProgram({}, ProgramMainInformation("", "", "")),
"",
Queue(),
{},
MemoizationMap({}, {}),
)
# Save value in map
result = runner_memoized_function_call(function_name, function, params, hidden_params)
result = memoized_call(function_name, function, params, hidden_params)
assert result == expected_result
# Test if value is actually saved by calling another function that does not return the expected result
result2 = runner_memoized_function_call(function_name, lambda *_: None, params, hidden_params)
result2 = memoized_call(function_name, lambda *_: None, params, hidden_params)
assert result2 == expected_result


def test_file_mtime_exists() -> None:
with tempfile.NamedTemporaryFile() as file:
file_mtime = runner_filemtime(file.name)
assert file_mtime is not None
mtime = file_mtime(file.name)
assert mtime is not None


def test_file_mtime_not_exists() -> None:
file_mtime = runner_filemtime(f"file_not_exists.{datetime.now(tz=UTC).timestamp()}")
assert file_mtime is None
mtime = file_mtime(f"file_not_exists.{datetime.now(tz=UTC).timestamp()}")
assert mtime is None


@pytest.mark.parametrize(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any

import pytest
from safeds_runner.server.pipeline_manager import _get_placeholder_type
from safeds_runner.server._pipeline_manager import _get_placeholder_type


@pytest.mark.parametrize(
Expand Down
12 changes: 6 additions & 6 deletions tests/safeds_runner/server/test_websocket_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import simple_websocket
from quart.testing.connections import WebsocketDisconnectError
from safeds.data.tabular.containers import Table
from safeds_runner.server.json_encoder import SafeDsEncoder
from safeds_runner.server.messages import (
from safeds_runner.server._json_encoder import SafeDsEncoder
from safeds_runner.server._messages import (
Message,
MessageQueryInformation,
QueryWindow,
Expand All @@ -28,7 +28,7 @@
validate_placeholder_query_message_data,
validate_program_message_data,
)
from safeds_runner.server.server import SafeDsServer
from safeds_runner.server._server import SafeDsServer


@pytest.mark.parametrize(
Expand Down Expand Up @@ -369,9 +369,9 @@ async def test_should_execute_pipeline_return_exception(
"code": {
"": {
"gen_test_a": (
"import safeds_runner.server.pipeline_manager\n\ndef pipe():\n\tvalue1 ="
" 1\n\tsafeds_runner.server.pipeline_manager.runner_save_placeholder('value1',"
" value1)\n\tsafeds_runner.server.pipeline_manager.runner_save_placeholder('obj',"
"import safeds_runner\n\ndef pipe():\n\tvalue1 ="
" 1\n\tsafeds_runner.save_placeholder('value1',"
" value1)\n\tsafeds_runner.save_placeholder('obj',"
" object())\n"
),
"gen_test_a_pipe": (
Expand Down

0 comments on commit 6d8dde7

Please sign in to comment.