Repository navigation
feat!: sessions: get, logs, stop, wait until ready - #6
Merged
Merged
Conversation
The SDK becomes a bare library on the way to the next API: - remove the Rails playground (test/dummy, bin/playground, lib/octaspace/playground), MockTransport, the Rails Engine and the Appraisal/Rails matrix; the Railtie stays (no Rails dependency) - require Ruby >= 3.3 (3.2 is EOL); CI tests 3.3, 3.4 and 4.0 - CI: actions pinned to commit SHAs, read-only token, concurrency, runs on main and next and on every PR, strict gem build, bundler-audit job - Dependabot for bundler and actions, targeting next, 3-day cooldown - faraday >= 2.14.3 (fixes published advisories); minitest 6, current webmock/standard/rake; railties and puma removed - docs/GIT_WORKFLOW_NEXT.md: how to work with the next branch
Transport for the next API (api-dev.octa.space): - Authorization: Bearer <api_key>; a pasted "Bearer " prefix and whitespace are stripped; 401 with a non-octa_ak_ key explains that legacy tokens are refused - per-endpoint auth mode: :required raises AuthenticationError before any request when no key is configured, :optional sends the key when present, :none never sends it - default base URL https://api-dev.octa.space (BASE_URL_DEV); the production hosts still serve the legacy API - errors: 400 -> ValidationError, 409 -> ConflictError, 503 -> ServiceUnavailableError; message taken from {"message"}; ApiError exposes retry_after, rate_limit and body - RateLimit-* headers parsed into OctaSpace::RateLimit, the latest available as client.rate_limit; Retry-After as seconds or HTTP date - retries only for GET and idempotent requests, on network errors and 429/502/503/504, honouring Retry-After up to max_retry_after (60 s); POST start/restart are never retried - failover across base_urls only for GET; a request that changes state is never sent to a second host - JSON parsed by the SDK: empty 202/204 bodies are fine, a non-JSON 2xx body raises ApiError - logging is one line per request; headers (API key) and bodies are never logged, and on_request no longer sees headers - faraday-retry dependency removed
- client.compute: list (GET /services/compute, key optional), start (object -> 201, returns the uuid), start_batch (array -> 200, per-item BatchResult), restart (POST .../restart -> 202; no params restarts with the original ones, params replace all of them) - client.render: list, start(node_number:), start_batch - typed read-only models (OctaSpace::Model) for ComputeMachine, RenderMachine, Gpu, Reliability and BatchResult; unknown fields are kept and reachable via [] / to_h - listings repair "null" strings and string GPU integers so one misreporting node does not break the listing - request bodies carry only the parameters that were set (ssh/fm stay tri-state), unknown parameters raise ArgumentError; batch items get their position as id, duplicate ids raise ArgumentError - removed: services.mr, services.vpn, services.render, ProvisionRejectedError, PayloadHelpers.normalize_marketplace_bandwidth
- client.sessions: list (GET /sessions), get (GET /services/{uuid}/info),
logs(uuid, tail:) (GET /services/{uuid}/logs), stop (POST .../stop ->
202, retried as idempotent), wait_ready (polls until "ready", yields
each state, SessionStoppedError on 404, WaitTimeoutError), and
wait_stopped (polls until 404)
- typed sessions picked by the service discriminator: ComputeSession,
RenderSession, and a plain Session for an unknown service; NodeHw,
SessionSsh/SshEndpoint (endpoint prefers direct over proxy),
SessionLogs/LogEntry; started_time / time convert Unix milliseconds
- Model.redact: inspect hides ssh.web and fm, URLs that grant access
- removed: services.session(uuid) proxy (info/logs/stop),
logs(recent:), stop(score:), sessions.list(**params) and the old
Types::Session
This was referenced Nov 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #5. Running sessions: get, logs, stop and waiting.
client.sessionslistGET /sessionsArray<Types::Session>(running only, oldest first)get(uuid)GET /services/{uuid}/infoTypes::Sessionlogs(uuid, tail: nil)GET /services/{uuid}/logs?tail=Types::SessionLogsstop(uuid)POST /services/{uuid}/stopwait_ready(uuid, timeout:, interval: 3) { |s| … }getwait_stopped(uuid, timeout:, interval: 3)truestopsends no body and is retried like a GET, since stopping twice is safewait_readyyields every polled state (status,progress,pull_percent). It raisesSessionStoppedError(aNotFoundError) when the session stops, andWaitTimeoutErrorwhen the timeout runs out.Types
Session.buildpicks the class byservice:ComputeSession,RenderSession, or a plainSessionfor any other serviceready?/starting?/compute?/render?;started_timeconverts Unix milliseconds toTimeComputeSession:ports,urls,ssh,fm,envs,rx/tx, the prices fixed at start,min_rent_minutesSessionSsh:direct/proxy(SshEndpointwith host, port, user) andweb;endpointprefers direct. The docs say to passusertosshas a separate argument after--, since it comes from the image.NodeHw(diskin GB,net_*_mbps,gpus)SessionLogs:system(LogEntry#msg/ts/time),container(may benil),container_truncated?inspecthidesssh.webandfm, which grant access to the sessionRemoved
services.session(uuid)withinfo/logs/stop,logs(recent:),stop(score:),sessions.list(**params)and the oldTypes::Session.Verification
rake test: 0 failures;standardrb: clean