{"id":15044035,"url":"https://github.com/openfun/ralph","last_synced_at":"2025-04-22T10:23:46.645Z","repository":{"id":36984476,"uuid":"238470238","full_name":"openfun/ralph","owner":"openfun","description":":gear: Ralph, the ultimate Learning Record Store (and more!) for your learning analytics","archived":false,"fork":false,"pushed_at":"2024-09-24T11:31:11.000Z","size":15018,"stargazers_count":37,"open_issues_count":43,"forks_count":15,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-10-29T21:55:58.724Z","etag":null,"topics":["analytics","cli","data-stream","docker","elasticsearch","fastapi","gelf","k8s","learning-analytics","lrs","pydantic","python","stream-processing","xapi"],"latest_commit_sha":null,"homepage":"https://openfun.github.io/ralph/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openfun.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-05T14:31:27.000Z","updated_at":"2024-10-16T20:09:48.000Z","dependencies_parsed_at":"2023-11-15T10:38:56.142Z","dependency_job_id":"e4738bc2-7240-4f83-bf5c-376ab5a30e2c","html_url":"https://github.com/openfun/ralph","commit_stats":{"total_commits":698,"total_committers":27,"mean_commits":25.85185185185185,"dds":0.7650429799426934,"last_synced_commit":"1e3ebbab0b86e3ff393c50662552a5f975534775"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openfun%2Fralph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openfun%2Fralph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openfun%2Fralph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openfun%2Fralph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openfun","download_url":"https://codeload.github.com/openfun/ralph/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246193275,"owners_count":20738452,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","cli","data-stream","docker","elasticsearch","fastapi","gelf","k8s","learning-analytics","lrs","pydantic","python","stream-processing","xapi"],"created_at":"2024-09-24T20:49:59.164Z","updated_at":"2025-03-29T14:10:43.241Z","avatar_url":"https://github.com/openfun.png","language":"Python","readme":"\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://openfun.github.io/ralph\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/openfun/logos/main/ralph/ralph-color-dark.png\" alt=\"Ralph logo\" width=\"400\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003eRalph, the ultimate Learning Record Store (and more!) for your learning analytics\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://circleci.com/gh/openfun/ralph/tree/main\"\u003e\n    \u003cimg src=\"https://img.shields.io/circleci/build/gh/openfun/ralph/main?label=Tests\u0026logo=circleci\" alt=\"Tests Status\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/ralph-malph\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/ralph-malph?label=PyPI+package\" alt=\"PyPI package version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://pypi.org/project/ralph-malph\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/pyversions/ralph-malph?label=Python\" alt=\"Python versions supported\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://hub.docker.com/r/fundocker/ralph/tags\"\u003e\n    \u003cimg src=\"https://img.shields.io/docker/v/fundocker/ralph/latest?label=Docker+image\" alt=\"Docker image version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://hub.docker.com/r/openfuncharts/ralph/tags\"\u003e\n    \u003cimg src=\"https://img.shields.io/docker/v/openfuncharts/ralph?label=Helm+chart\u0026color=blue\" alt=\"Helm chart version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://discord.gg/vYx6YWxJCS\"\u003e\n    \u003cimg src=\"https://img.shields.io/discord/1082704478463082496?label=Discord\u0026logo=discord\u0026style=shield\" alt=\"Discord\"\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n**Documentation**: [https://openfun.github.io/ralph](https://openfun.github.io/ralph)\n\n**Source Code**: [https://github.com/openfun/ralph](https://github.com/openfun/ralph)\n\n---\n\nRalph is a toolbox for your learning analytics, it can be used as a:\n\n- **[LRS](https://en.wikipedia.org/wiki/Learning_Record_Store)**, a HTTP API server to collect xAPI statements (learning events), following the [ADL LRS standard](https://github.com/adlnet/xAPI-Spec/blob/master/xAPI-Communication.md#partthree)\n- **command-line interface** (CLI), to build data pipelines the UNIX-way™️,\n- **library**, to fetch learning events from various backends, (de)serialize or\n    convert them from and to various standard formats such as\n    [xAPI](https://adlnet.gov/projects/xapi/), or\n    [openedx](https://docs.openedx.org/en/latest/developers/references/internal_data_formats/tracking_logs/index) html\n\n## ⚡️ Quick start guide: Run the LRS server\n\n\u003e Preliminary notes:\n\u003e\n\u003e 1. [`curl`](https://curl.se), [`jq`](https://stedolan.github.io/jq/) and\n\u003e    [`docker compose`](https://docs.docker.com/compose/) are required to run\n\u003e    some commands of this tutorial. Make sure they are installed first.\n\u003e\n\u003e 2. In order to run the Elasticsearch backend locally on GNU/Linux operating\n\u003e    systems, ensure that your virtual memory limits are not too low and\n\u003e    increase them (temporally) if needed by typing this command from your\n\u003e    terminal (as `root` or using `sudo`): `sysctl -w vm.max_map_count=262144`\n\u003e\n\u003e Reference:\n\u003e https://www.elastic.co/guide/en/elasticsearch/reference/master/vm-max-map-count.html\n\nTo bootstrap a test environment on your machine, clone this project first and\nrun the `bootstrap` Makefile target:\n\n```bash\nmake bootstrap\n```\n\nThis command will create required `.env` file (you may want to edit it for your\ntest environment), build the Ralph's Docker image and start a single node\nElasticsearch cluster _via_ Docker compose.\n\nYou can check the `elasticsearch` service status using the `status` helper:\n\n```bash\nmake status # This is an alias for: docker compose ps\n```\n\nYou may now start the LRS server using:\n\n```bash\nmake run\n```\n\nThe server should be up and running at\n[http://localhost:8100](http://localhost:8100). You can check its status using\nthe heartbeat probe:\n\n```bash\ncurl http://localhost:8100/__heartbeat__\n```\n\nThe expected answer should be:\n\n```json\n{\"database\":\"ok\"}\n```\n\nIf the database status is satisfying, you are now ready to send xAPI statements\nto the LRS:\n\n```bash\ngunzip -c data/statements.json.gz | \\\nhead -n 100 | \\\njq -s . | \\\ncurl -Lk \\\n    --user ralph:secret \\\n    -X POST \\\n    -H \"Content-Type: application/json\" \\\n    -d @- \\\n    http://localhost:8100/xAPI/statements/\n```\n\nThe command above fetches one hundred (100) example xAPI statements from our\n[Potsie](https://github.com/openfun/potsie) project and sends them to the LRS\nusing `curl`.\n\nYou can get them back from the LRS using `curl` to query the\n`/xAPI/statements/` endpoint:\n\n```bash\ncurl -s \\\n    --user ralph:secret \\\n    -H \"Content-Type: application/json\" \\\n    http://localhost:8100/xAPI/statements/ \\ |\njq\n```\n\n\u003e Note that using `jq` is optional in this case, it is used to improve response\n\u003e readability. It is not required to install it to run this snippet.\n\n## ⚡️ Quick start guide: Manipulate data with the CLI\n\n### With the Docker image\n\nRalph is distributed as a [Docker\nimage](https://hub.docker.com/repository/docker/fundocker/ralph). If\n[Docker](https://docs.docker.com/get-docker/) is installed on your machine, it\ncan be pulled from DockerHub:\n\n```bash\ndocker run --pull always --rm fundocker/ralph:latest ralph --help\n```\n\n### With the Python package\n\nRalph is distributed as a standard python package; it can be installed _via_\n`pip` or any other python package manager (_e.g._ Poetry, Pipenv, etc.):\n\n```bash\n# Install the full package\npip install \\\n    ralph-malph[full]\n\n# Install only the core package (library usage without backends, CLI and LRS)\npip install ralph-malph\n```\n\nIf you installed the full package (including the CLI, LRS and supported\nbackends), the `ralph` command should be available in your `PATH`. Try to\ninvoke the program usage thanks to the `--help` flag:\n\n```bash\nralph --help\n```\n\nYou should see a list of available commands and global flags for `ralph`. Note\nthat each command has its own usage that can be invoked _via_:\n\n```bash\nralph COMMAND --help\n```\n\n\u003e You should substitute `COMMAND` by the target command, _e.g._ `list`, to see\n\u003e its usage.\n\n## Migrating\n\nSome major version changes require updating persistence layers. Check out the [migration guide](https://github.com/openfun/ralph/blob/main/UPGRADE.md) for more information.\n\n## Contributing\n\nThis project is intended to be community-driven, so please, do not hesitate to\nget in touch if you have any question related to our implementation or design\ndecisions.\n\nWe try to raise our code quality standards and expect contributors to follow\nthe recommendations from our\n[handbook](https://handbook.openfun.fr).\n\n## Useful commands\n\n\nYou can explore all available rules using:\n\n```bash\nmake help\n```\nbut here are some of them:\n\n- Bootstrap the project: `make bootstrap`\n- Run tests: `make test`\n- Run all linters: `make lint`\n- If you add new dependencies to the project, you will have to rebuild the Docker\nimage (and the development environment): `make down \u0026\u0026 make bootstrap`\n\n## License\n\nThis work is released under the MIT License (see [LICENSE](./LICENSE.md)).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenfun%2Fralph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenfun%2Fralph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenfun%2Fralph/lists"}