Upgrade¶
All instructions to upgrade this project from one release to the next will be documented in this file. Upgrades must be run sequentially, meaning you should not skip minor/major releases while upgrading (fix releases can be skipped).
This project adheres to Semantic Versioning.
5.1.0 — partial success (issue #622)¶
partialSuccess (issue #622)¶
Optional bulk ingestion when some statements in a batch are invalid.
This feature is disabled by default and does nothing until you turn it on.
POST /xAPI/statements stays atomic (xAPI-strict) unless one of the following
applies:
| Trigger | Set by |
|---|---|
?partialSuccess=true or ?ignoreInvalid=true |
the client, per request |
RALPH_LRS_PARTIAL_SUCCESS_DEFAULT=true (default: false) |
the server, globally |
Clients that cannot add a query parameter — the Moodle logstore_xapi plugin is
the typical case — are only covered by the server setting. Upgrading the
image without setting it changes nothing for them.
Once the server default is on, a client can still force strict behaviour per
request with ?partialSuccess=false.
See the partial success tutorial.
Elasticsearch per-statement isolation (5.0.2-beta1)¶
In partial-success mode, statements that pass Pydantic validation but fail Elasticsearch
indexation are skipped individually (_write_statements_partial) instead of failing the
whole batch with HTTP 500.
Elasticsearch-compatible dict keys (5.1.0)¶
When RUNSERVER_BACKEND=es and RALPH_LRS_ELASTICSEARCH_VALIDATE_KEYS=true (default),
POST /xAPI/statements rejects statements whose JSON object keys are incompatible with
Elasticsearch before indexation:
- empty string key (
"") — e.g. quiz match extension with no response key - non-IRI key containing
.— e.g.nested.keyinside an extension map
xAPI extension IRI keys (URLs with dots) remain valid. Only local / non-IRI keys with a dot are rejected.
Opt out: RALPH_LRS_ELASTICSEARCH_VALIDATE_KEYS=false.
Enable
RALPH_LRS_PARTIAL_SUCCESS_DEFAULTfirst. In strict mode this check rejects the whole batch before any write, so nothing is indexed. Up to5.0.2-beta1, such a batch returned HTTP 500 while the valid statements were still written to Elasticsearch. Deployments relying on that partial write will lose those statements unless partial-success mode is turned on beforehand.
4.x to 5.y¶
Upgrade learning events models¶
xAPI learning statements validator and converter are built with Pydantic. Ralph 5.x
is compatible with Pydantic 2.x. Please refer to Pydantic migration
guide if you are using Ralph models
feature.
Most of fields in Pydantic models that are optional are set with
Noneas default value in Ralph 5.y. If you serialize some Pydantic models from ralph and want to keep the same content in your serialization, please setexclude_nonetoTruein the serialization methodmodel_dump.
3.x to 4.y¶
Upgrade user credentials¶
To conform to xAPI specifications, we need to represent users as xAPI Agents. You must therefore delete and re-create the credentials file using the updated cli, OR you can modify it directly to add the agents field. The credentials file is located in { RALPH_APP_DIR }/{ RALPH_AUTH_FILE } (defaults to .ralph/auth.json). Each user profile must follow the following pattern (see this post for examples of valid agent objects) :
{
"username": "USERNAME_UNCHANGED",
"hash": "PASSWORD_HASH_UNCHANGED",
"scopes": [ LIST_OF_SCOPES_UNCHANGED ],
"agent": { A_VALID_AGENT_OBJECT }
}
For example here is a valid auth.json file:
[
{
"username": "john.doe@example.com",
"hash": "$2b$12$yBXrzIuRIk6yaft5KUgVFOIPv0PskCCh9PXmF2t7pno.qUZ5LK0D2",
"scopes": ["example_scope"],
"agent": {
"mbox": "mailto:john.doe@example.com"
}
},
{
"username": "simon.says@example.com",
"hash": "$2b$12$yBXrzIuRIk6yaft5KUgVFOIPv0PskCCh9PXmF2t7pno.qUZ5LK0D2",
"scopes": ["second_scope", "third_scope"],
"agent": {
"account": {
"name": "simonsAccountName",
"homePage": "http://www.exampleHomePage.com"
}
}
}
]
Upgrade Ralph CLI usage¶
If you are using Ralph’s CLI, the following changes may affect you:
- The
ralph fetchcommand changed toralph read - The
-b wsbackend option changed to-b async_ws- The corresponding
--ws-urioption changed to--async-ws-uri
- The corresponding
- The
-c --chunk-sizeoption changed to-s --chunk-size -
The
DEFAULT_BACKEND_CHUNK_SIZEenvironment variable configuration is removed in favor of allowing each backend to define their own defaults:Backend Environment variable for default (read) chunk size async_es/es RALPH_BACKENDS__DATA__ES__READ_CHUNK_SIZE=500 async_lrs/lrs RALPH_BACKENDS__DATA__LRS__READ_CHUNK_SIZE=500 async_mongo/mongo RALPH_BACKENDS__DATA__MONGO__READ_CHUNK_SIZE=500 clickhouse RALPH_BACKENDS__DATA__CLICKHOUSE__READ_CHUNK_SIZE=500 fs RALPH_BACKENDS__DATA__FS__READ_CHUNK_SIZE=4096 ldp RALPH_BACKENDS__DATA__LDP__READ_CHUNK_SIZE=4096 s3 RALPH_BACKENDS__DATA__S3__READ_CHUNK_SIZE=4096 swift RALPH_BACKENDS__DATA__SWIFT__READ_CHUNK_SIZE=4096 -
The
ralph pushcommand changed toralph write - The
-c --chunk-sizeoption changed to-s --chunk-size -
The
DEFAULT_BACKEND_CHUNK_SIZEenvironment variable configuration is removed in favor of allowing each backend to define their own defaults:Backend Environment variable for default (write) chunk size async_es/es RALPH_BACKENDS__DATA__ES__WRITE_CHUNK_SIZE=500 async_lrs/lrs RALPH_BACKENDS__DATA__LRS__WRITE_CHUNK_SIZE=500 async_mongo/mongo RALPH_BACKENDS__DATA__MONGO__WRITE_CHUNK_SIZE=500 clickhouse RALPH_BACKENDS__DATA__CLICKHOUSE__WRITE_CHUNK_SIZE=500 fs RALPH_BACKENDS__DATA__FS__WRITE_CHUNK_SIZE=4096 ldp RALPH_BACKENDS__DATA__LDP__WRITE_CHUNK_SIZE=4096 s3 RALPH_BACKENDS__DATA__S3__WRITE_CHUNK_SIZE=4096 swift RALPH_BACKENDS__DATA__SWIFT__WRITE_CHUNK_SIZE=4096 -
Environment variables used to configure backend options for CLI usage (read/write/list commands) changed their prefix:
RALPH_BACKENDS__{{DATABASE or HTTP or STORAGE or STREAM}}__{{BACKEND}}__{{OPTION}}changed toRALPH_BACKENDS__DATA__{{BACKEND}}__{{OPTION}} - Environment variables used to configure backend options for LRS usage
(runserver command) changed their prefix:
RALPH_BACKENDS__{{DATABASE}}__{{BACKEND}}__{{OPTION}}changed toRALPH_BACKENDS__LRS__{{BACKEND}}__{{OPTION}}
Upgrade history syntax¶
CLI syntax has been changed from fetch & push to read & write affecting the command history. You must replace the command history after updating:
- locate your history file path, which is in { RALPH_APP_DIR }/history.json (defaults to .ralph/history.json)
- run the commands below to update history
sed -i 's/"fetch"/"read"/g' { my_history_file_path }
sed -i 's/"push"/"write"/g' { my_history_file_path }
Upgrade Ralph library usage (backends)¶
If you use Ralph’s backends in your application, the following changes might affect you:
Backends from ralph.backends.database, ralph.backends.http, ralph.backends.stream,
and ralph.backends.storage packages have moved to a single ralph.backends.data
package.
| Ralph v3 (database/http/storage/stream) backends | Ralph v4 data backends |
|---|---|
ralph.backends.database.clickhouse.ClickHouseDatabase |
ralph.backends.data.clickhouse.ClickHouseDataBackend |
ralph.backends.database.es.ESDatabase |
ralph.backends.data.es.ESDataBackend |
ralph.backends.database.mongo.MongoDatabase |
ralph.backends.data.mongo.MongoDataBackend |
ralph.backends.http.async_lrs.AsyncLRSHTTP |
ralph.backends.data.async_lrs.AsyncLRSDataBackend |
ralph.backends.http.lrs.LRSHTTP |
ralph.backends.data.lrs.LRSDataBackend |
ralph.backends.storage.fs.FSStorage |
ralph.backends.data.fs.FSDataBackend |
ralph.backends.storage.ldp.LDPStorage |
ralph.backends.data.ldp.LDPDataBackend |
ralph.backends.storage.s3.S3Storage |
ralph.backends.data.s3.S3DataBackend |
ralph.backends.storage.swift.SwiftStorage |
ralph.backends.data.swift.SwiftDataBackend |
ralph.backends.stream.ws.WSStream |
ralph.backends.data.async_ws.AsyncWSDataBackend |
LRS-specific query_statements and query_statements_by_ids database backend methods
have moved to a dedicated ralph.backends.lrs.BaseLRSBackend interface that extends the
data backend interface with these two methods.
The query_statements_by_ids method return type changed to Iterator[dict].
| Ralph v3 database backends for lrs usage | Ralph v4 LRS data backends |
|---|---|
ralph.backends.database.clickhouse.ClickHouseDatabase |
ralph.backends.lrs.clickhouse.ClickHouseLRSBackend |
ralph.backends.database.es.ESDatabase |
ralph.backends.lrs.es.ESLRSBackend |
ralph.backends.database.mongo.MongoDatabase |
ralph.backends.lrs.mongo.MongoLRSBackend |
Backend interface differences
- Data backends are read-only by default
- Data backends that support write operations inherit from the
ralph.backends.data.base.Writableinterface - Data backends that support list operations inherit from the
ralph.backends.data.base.Listableinterface - Data backends that support LRS operations
(
query_statements/query_statements_by_ids) inherit from theralph.backends.lrs.BaseLRSBackendinterface __init__(self, **kwargs)changed to__init__(self, settings: DataBackendSettings)where each DataBackend defines it’s own Settings object For example theFSDataBackendusesFSDataBackendSettingsstreamandgetmethods changed toreadputmethods changed towrite
Backend usage migration example
Ralph v3 using ESDatabase:
from ralph.conf import ESClientOptions
from ralph.backends.database.es import ESDatabase, ESQuery
# Instantiate the backend.
backend = ESDatabase(
hosts="localhost",
index="statements"
client_options=ESClientOptions(verify_certs=False)
)
# Read records from backend.
query = ESQuery(query={"query": {"term": {"modulo": 0}}})
es_statements = list(backend.get(query))
# Write records to backend.
backend.put([{"id": 1}])
Ralph v4 using ESDataBackend:
from ralph.backends.data.es import (
ESClientOptions,
ESDataBackend,
ESDataBackendSettings,
ESQuery,
)
# Instantiate the backend.
settings = ESDataBackendSettings(
HOSTS="localhost",
INDEX="statements",
CLIENT_OPTIONS=ESClientOptions(verify_certs=False)
)
backend = ESDataBackend(settings)
# Read records from backend.
query = ESQuery(query={"term": {"modulo": 0}})
es_statements = list(backend.read(query))
# Write records to backend.
backend.write([{"id": 1}])
Upgrade ClickHouse schema¶
If you are using the ClickHouse backend, schema changes have been made to drop the existing JSON column in favor of the String version of the same data. See this issue for details.
Ralph does not manage the ClickHouse schema, so if you have existing data you will need to manually alter it as an admin user. Note: this will rewrite the statements table, which may take a long time if you have many rows. The command to run is: