diff --git a/backend/fluksio/api/deps.py b/backend/fluksio/api/deps.py index 7a266d6..a70f801 100644 --- a/backend/fluksio/api/deps.py +++ b/backend/fluksio/api/deps.py @@ -527,7 +527,7 @@ def get_current_user(request: Request, session: SessionDep, token: TokenDep) -> if user is None or not user.is_active: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, - detail="This session is no longer valid — please log in again", + detail="This session is no longer valid. Please log in again", ) return user diff --git a/backend/fluksio/api/routes/dashboards.py b/backend/fluksio/api/routes/dashboards.py index 9f4b260..1058f75 100644 --- a/backend/fluksio/api/routes/dashboards.py +++ b/backend/fluksio/api/routes/dashboards.py @@ -182,7 +182,7 @@ async def discard_dashboard_draft(name: str, store: DashboardStoreDep) -> Any: raise HTTPException( status_code=400, detail=( - f"Dashboard '{name}' has never been published — delete it instead " + f"Dashboard '{name}' has never been published. Delete it instead " "of discarding it" ), ) diff --git a/backend/fluksio/api/routes/flows.py b/backend/fluksio/api/routes/flows.py index 44fbfcd..e3f79ba 100644 --- a/backend/fluksio/api/routes/flows.py +++ b/backend/fluksio/api/routes/flows.py @@ -303,7 +303,7 @@ def _require_enabled(controller: FlowController, name: str) -> None: if not controller.is_enabled(name): raise HTTPException( status_code=409, - detail=f"Flow '{name}' is stopped — start it before running it", + detail=f"Flow '{name}' is stopped. Start it before running it", ) @@ -601,7 +601,7 @@ async def discard_draft(name: str, controller: FlowControllerDep) -> Any: raise HTTPException( status_code=400, detail=( - f"Flow '{name}' has never been published — delete it instead of " + f"Flow '{name}' has never been published. Delete it instead of " "discarding it" ), ) diff --git a/backend/fluksio/flow/controller.py b/backend/fluksio/flow/controller.py index f921b7f..194429c 100644 --- a/backend/fluksio/flow/controller.py +++ b/backend/fluksio/flow/controller.py @@ -358,7 +358,7 @@ NODE_TYPES: dict[str, NodeType] = { ), "websocket": NodeType( title="WebSocket", - description="Listen on a socket, or send to it — as a client or a server.", + description="Listen on a socket, or send to it, as a client or a server.", cls=WebSocketNode, params_schema=_schema_of(WebSocketNode), ), @@ -2133,8 +2133,8 @@ def _collect_issues( ValidationIssue( code="unauthenticated_hook", message=( - f"Hook '{entry.node.local_id}' has no secret — " - "anyone who knows its URL can reach it." + f"Hook '{entry.node.local_id}' has no secret. " + "Anyone who knows its URL can reach it." ), flow=entry.flow, node=entry.id, diff --git a/backend/fluksio/flow/messages.py b/backend/fluksio/flow/messages.py index fc09483..8fb16b8 100644 --- a/backend/fluksio/flow/messages.py +++ b/backend/fluksio/flow/messages.py @@ -256,7 +256,7 @@ class MessageSpec(BaseModel): raise TypeError( f"{where}: {stray} cannot travel as JSON. A subset with nothing " "in it, or a division that had no denominator, is what usually " - "produces one — publish None, or a number that says so." + "produces one. Publish None, or a number that says so." ) if self.dtype is DType.SERIES: ok = _is_series(value) diff --git a/backend/fluksio/flow/nodes/websocket.py b/backend/fluksio/flow/nodes/websocket.py index 0d65a10..dfdbc0b 100644 --- a/backend/fluksio/flow/nodes/websocket.py +++ b/backend/fluksio/flow/nodes/websocket.py @@ -91,7 +91,7 @@ class WebSocketNode(Node): on_connect: list[Any] = Field( default_factory=list, description=( - "Frames sent after every (re)connect, client only — the " + "Frames sent after every (re)connect, client only: the " "subscribe or auth message many APIs expect. A string goes " "raw, anything else as JSON; an item may be a secret reference." ), diff --git a/backend/fluksio/flow/resources.py b/backend/fluksio/flow/resources.py index 0e05c22..67da97b 100644 --- a/backend/fluksio/flow/resources.py +++ b/backend/fluksio/flow/resources.py @@ -299,7 +299,7 @@ def resolve_flavor(wanted: Resources) -> Resources: row = session.get(Flavor, wanted.flavor) if row is None: raise UnknownFlavor( - f"flavor '{wanted.flavor}' does not exist — `fluksio flavors` lists them" + f"flavor '{wanted.flavor}' does not exist. `fluksio flavors` lists them" ) # Built fresh rather than copied, so the flavor-and-numbers check runs on # the result and this cannot quietly produce something invalid. diff --git a/backend/fluksio/flow/runs.py b/backend/fluksio/flow/runs.py index 5f12f2b..476bed4 100644 --- a/backend/fluksio/flow/runs.py +++ b/backend/fluksio/flow/runs.py @@ -282,8 +282,8 @@ def _from_run( run_id, _, output = spelling.partition(".") if not run_id or not output: raise RunRejected( - f"Parameter '{key}': '{RUN_REF_PREFIX}{spelling}' names no output — " - f"write {RUN_REF_PREFIX}." + f"Parameter '{key}': '{RUN_REF_PREFIX}{spelling}' names no output. " + f"Write {RUN_REF_PREFIX}." ) run = session.get(Run, run_id) if run is None: diff --git a/backend/fluksio/flow/schemas.py b/backend/fluksio/flow/schemas.py index c63f4f3..acd4165 100644 --- a/backend/fluksio/flow/schemas.py +++ b/backend/fluksio/flow/schemas.py @@ -38,7 +38,7 @@ def _megabytes(value: Any) -> Any: return value match = _SIZE.match(value) if not match: - raise ValueError(f"'{value}' is not a size — write 512M, 2G, or 512") + raise ValueError(f"'{value}' is not a size. Write 512M, 2G, or 512") amount, unit = int(match.group(1)), (match.group(2) or "m").lower() return amount * 1024 if unit.startswith("g") else amount @@ -49,7 +49,7 @@ def _seconds(value: Any) -> Any: return value match = _SPAN.match(value) if not match: - raise ValueError(f"'{value}' is not a duration — write 90s, 30m, 2h, or 90") + raise ValueError(f"'{value}' is not a duration. Write 90s, 30m, 2h, or 90") return int(match.group(1)) * _SPAN_SECONDS[(match.group(2) or "s").lower()] @@ -95,7 +95,7 @@ class Resources(BaseModel): description=( "Megabytes held for the whole execution; accepts '512M' or '2G'. " "Counted against machines that said how much they have, and " - "ignored by those that did not — which is a machine with nothing " + "ignored by those that did not, which is a machine with nothing " "to say about memory, not one with none." ), ) @@ -113,15 +113,15 @@ class Resources(BaseModel): description=( "How long one execution is expected to take; accepts '30m' or " "'2h'. A statement about the node for whoever is planning around " - "it, not a limit — the limit is `timeout`." + "it, not a limit. The limit is `timeout`." ), ) env: dict[str, str] = Field( default_factory=dict, description=( "Extra environment for the worker this node runs in, applied over " - "what the allocation derives. Where a library's own tuning goes — " - "XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION — since those are " + "what the allocation derives. Where a library's own tuning goes " + "(XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION), since those are " "composed strings the engine must not invent." ), ) @@ -140,8 +140,8 @@ class Resources(BaseModel): """ if self.flavor and (self.cpus != 1 or self.gpus != 0 or self.ram is not None): raise ValueError( - f"flavor '{self.flavor}' already says how much — " - "drop cpus, gpus and ram, or drop the flavor" + f"flavor '{self.flavor}' already says how much. " + "Drop cpus, gpus and ram, or drop the flavor" ) return self @@ -203,8 +203,8 @@ class NodeDef(BaseModel): resources: Resources | None = Field( default=None, description=( - "What one execution of this node holds while it runs. Absent — the " - "default — means it is not accounted for and shares the engine's " + "What one execution of this node holds while it runs. Absent (the " + "default) means it is not accounted for and shares the engine's " "workers, which is right for everything that is not compute-heavy." ), ) @@ -222,7 +222,7 @@ class NodeDef(BaseModel): description=( "What those modules hashed to at sync. The engine hashes them " "again when a run is claimed, and falls back to this when it " - "cannot see the files — a worker on another machine." + "cannot see the files, as a worker on another machine does." ), ) diff --git a/backend/fluksio/flow/secrets.py b/backend/fluksio/flow/secrets.py index 0774f85..117a9ac 100644 --- a/backend/fluksio/flow/secrets.py +++ b/backend/fluksio/flow/secrets.py @@ -31,7 +31,7 @@ class SecretNotFound(KeyError): self.name = name def __str__(self) -> str: - return f"No secret named '{self.name}' — add it under Secrets." + return f"No secret named '{self.name}'. Add it under Secrets." def fernet(key: str) -> Fernet: @@ -60,7 +60,7 @@ class SecretsStore: # flows coming up with silently missing credentials are far harder # to diagnose than a node that reports why it did not load. raise SecretsUnreadable( - f"Cannot decrypt {self._path} — it was written with a " + f"Cannot decrypt {self._path}. It was written with a " "different SECRET_KEY. Re-encrypt it with " "scripts/rotate_secret_key.py." ) from exc diff --git a/frontend/src/client/schemas.gen.ts b/frontend/src/client/schemas.gen.ts index a1b71b4..1d5e0d1 100644 --- a/frontend/src/client/schemas.gen.ts +++ b/frontend/src/client/schemas.gen.ts @@ -2764,7 +2764,7 @@ export const NodeDef_InputSchema = { type: 'null' } ], - description: "What one execution of this node holds while it runs. Absent — the default — means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy." + description: "What one execution of this node holds while it runs. Absent (the default) means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy." }, code_files: { additionalProperties: { @@ -2777,7 +2777,7 @@ export const NodeDef_InputSchema = { code_digest: { type: 'string', title: 'Code Digest', - description: 'What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files — a worker on another machine.', + description: 'What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files, as a worker on another machine does.', default: '' } }, @@ -2884,7 +2884,7 @@ export const NodeDef_OutputSchema = { type: 'null' } ], - description: "What one execution of this node holds while it runs. Absent — the default — means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy." + description: "What one execution of this node holds while it runs. Absent (the default) means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy." }, code_files: { additionalProperties: { @@ -2897,7 +2897,7 @@ export const NodeDef_OutputSchema = { code_digest: { type: 'string', title: 'Code Digest', - description: 'What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files — a worker on another machine.', + description: 'What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files, as a worker on another machine does.', default: '' } }, @@ -3693,7 +3693,7 @@ export const ResourcesSchema = { } ], title: 'Ram', - description: "Megabytes held for the whole execution; accepts '512M' or '2G'. Counted against machines that said how much they have, and ignored by those that did not — which is a machine with nothing to say about memory, not one with none." + description: "Megabytes held for the whole execution; accepts '512M' or '2G'. Counted against machines that said how much they have, and ignored by those that did not, which is a machine with nothing to say about memory, not one with none." }, flavor: { anyOf: [ @@ -3718,7 +3718,7 @@ export const ResourcesSchema = { } ], title: 'Duration S', - description: "How long one execution is expected to take; accepts '30m' or '2h'. A statement about the node for whoever is planning around it, not a limit — the limit is `timeout`." + description: "How long one execution is expected to take; accepts '30m' or '2h'. A statement about the node for whoever is planning around it, not a limit. The limit is `timeout`." }, env: { additionalProperties: { @@ -3726,7 +3726,7 @@ export const ResourcesSchema = { }, type: 'object', title: 'Env', - description: "Extra environment for the worker this node runs in, applied over what the allocation derives. Where a library's own tuning goes — XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION — since those are composed strings the engine must not invent." + description: "Extra environment for the worker this node runs in, applied over what the allocation derives. Where a library's own tuning goes (XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION), since those are composed strings the engine must not invent." } }, additionalProperties: false, diff --git a/frontend/src/client/types.gen.ts b/frontend/src/client/types.gen.ts index 1366835..538ac14 100644 --- a/frontend/src/client/types.gen.ts +++ b/frontend/src/client/types.gen.ts @@ -928,7 +928,7 @@ export type NodeDef_Input = { */ cache?: boolean; /** - * What one execution of this node holds while it runs. Absent — the default — means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy. + * What one execution of this node holds while it runs. Absent (the default) means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy. */ resources?: (Resources | null); /** @@ -938,7 +938,7 @@ export type NodeDef_Input = { [key: string]: (string); }; /** - * What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files — a worker on another machine. + * What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files, as a worker on another machine does. */ code_digest?: string; }; @@ -982,7 +982,7 @@ export type NodeDef_Output = { */ cache?: boolean; /** - * What one execution of this node holds while it runs. Absent — the default — means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy. + * What one execution of this node holds while it runs. Absent (the default) means it is not accounted for and shares the engine's workers, which is right for everything that is not compute-heavy. */ resources?: (Resources | null); /** @@ -992,7 +992,7 @@ export type NodeDef_Output = { [key: string]: (string); }; /** - * What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files — a worker on another machine. + * What those modules hashed to at sync. The engine hashes them again when a run is claimed, and falls back to this when it cannot see the files, as a worker on another machine does. */ code_digest?: string; }; @@ -1232,7 +1232,7 @@ export type Resources = { */ gpus?: number; /** - * Megabytes held for the whole execution; accepts '512M' or '2G'. Counted against machines that said how much they have, and ignored by those that did not — which is a machine with nothing to say about memory, not one with none. + * Megabytes held for the whole execution; accepts '512M' or '2G'. Counted against machines that said how much they have, and ignored by those that did not, which is a machine with nothing to say about memory, not one with none. */ ram?: (number | null); /** @@ -1240,11 +1240,11 @@ export type Resources = { */ flavor?: (string | null); /** - * How long one execution is expected to take; accepts '30m' or '2h'. A statement about the node for whoever is planning around it, not a limit — the limit is `timeout`. + * How long one execution is expected to take; accepts '30m' or '2h'. A statement about the node for whoever is planning around it, not a limit. The limit is `timeout`. */ duration_s?: (number | null); /** - * Extra environment for the worker this node runs in, applied over what the allocation derives. Where a library's own tuning goes — XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION — since those are composed strings the engine must not invent. + * Extra environment for the worker this node runs in, applied over what the allocation derives. Where a library's own tuning goes (XLA_FLAGS, XLA_PYTHON_CLIENT_MEM_FRACTION), since those are composed strings the engine must not invent. */ env?: { [key: string]: (string);