Code Monkey home page Code Monkey logo

warren's Introduction

Warren

Warren is a visualization platform for learning analytics.

⚠️ This project is a Proof Of Concept not suitable for production yet. ⚠️

Quick start guide (for developers)

Once you've cloned the project, it can be bootstrapped using the eponym GNU Make target:

$ make bootstrap

Once frontend and API backend Docker images have been built, you can start the API backend and frontend development servers using:

$ make run

You may now take a look at the frontend development server at: http://localhost:8090/development

Click on Submit Query and scroll down to get the development LTI iframe rendering.

To run tests and linters, there are commands for that! You can list them using:

$ make help

Contributing

This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.

We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.

You can ensure your code is compliant by running the following commands:

  • make lint to run the linters
  • make test to run the tests

Note that we also provide a git pre-commit hook to ease your life:

make git-hook-pre-commit

License

This work is released under the MIT License (see LICENSE).

warren's People

Contributors

cyrillay avatar jmaupetit avatar lebaudantoine avatar lebrunthibault avatar lunika avatar quitterie-lcs avatar renovate[bot] avatar wilbrdt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

lifestreamvii

warren's Issues

[CLI] Add verbose mode for `inspect` indicator command

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
The inspect command for indicator uses indicator signature to describe parameters. However, when parameters are custom types such as Pydantic model, the user does not know from the command output how to fulfill the parameter. It is necessary to refer to the indicator documentation.

Describe the solution you'd like
Add a verbose mode to the inspect command so that for users unfamiliar with some indicators have hints about the custom parameters.

Do you want to work on it through a Pull Request?
Yes ! ⌨️

🧱(backend) Add API backend health check routes

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
When deploying an application in production (e.g. in a Kubernetes environment), we need a way to check its status so that we can restart it if required.

Describe the solution you'd like
We usually implement Mozilla's Dockerflow endpoints.

Discovery, Documentation, Adoption, Migration Strategy
We've already achieved that in a similar FastAPI project: Ralph/health.py

Do you want to work on it through a Pull Request?
Yup.

[Experience Index] Restrict timestamps to UTC timezone

Bug Report

Expected behavior/code
All date manipulations and storage should strictly adhere to UTC timezone conventions.

Actual Behavior
Dates can be stored with different timezones in the database, leading to inconsistent timezone handling upon retrieval.

Handle daylight saving time (DST) and standard time (STD) disparities

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.

The API lacks support for date ranges spanning DST to STD transitions due to new query parameter validation.
The start and end dates of a range must have the same UTC offset.

Example:
'Europe/Paris' is UTC+02:00 in STD and UTC+01:00 in DST.

When querying a range from 15th of October to the 30th of October, the API will respond a 422 unprocessable entity.

Describe the solution you'd like

I want to pass a date range that shares a timezone, not just a UTC offset.
I've added an extra step in the frontend to ensure that both the start and end dates have the same UTC offset.

Describe alternatives you've considered

  • Add a timezone parameter when querying the API?

Discovery, Documentation, Adoption, Migration Strategy
If you want to understand DST and STD abbreviation, please take a look here

Completion threshold

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
Make accessible the completion threshold of a video to the frontend. This metric was supported in Postie, and designed in the Figma Wireframe.

The completion threshold stands as a value assigned to each video and configured within Marsha. Presently, we employ this value to ascertain the completion status of views and downloads.

Describe the solution you'd like

Our ideal solution involves the implementation of a straightforward API endpoint. This endpoint will require the video's unique identifier (UID) as a request parameter. The primary purpose of this API is to procure contextual information to the video, including its completion threshold.

Describe alternatives you've considered

  • Experience index and resource's context retrieval: This involves waiting for the experience index and subsequently retrieving the video's context, which encompasses the completion threshold.

  • Integration with existing endpoints: Another consideration is to incorporate this functionality into the existing views or download endpoints.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

  • ⬆️(project) upgrade js dependencies (@babel/core, @changesets/cli, @openfun/cunningham-react, @tanstack/react-query, @tanstack/react-query-devtools, @types/node, @types/react, @types/react-dom, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, @vitejs/plugin-react, axios, dayjs, echarts, esbuild-sass-plugin, eslint, eslint-config-airbnb-typescript, eslint-config-next, eslint-plugin-compat, eslint-plugin-formatjs, eslint-plugin-react, eslint-plugin-react-hooks, prettier, react, react-dom, sass, tsup, turbo, typescript, vite, yarn)
  • ⬆️(project) upgrade python dependencies (ci/twine, dev/Faker, dev/freezegun, dev/pandas-stubs, dev/polyfactory, dev/ruff, fastapi, mike, mkdocs-material, ralph-malph, sentry-sdk, sqlmodel, uvicorn)

Detected dependencies

npm
src/frontend/apps/web/package.json
  • @openfun/cunningham-react 2.4.0
  • @vitejs/plugin-react 4.2.1
  • react 18.2.0
  • react-dom 18.2.0
  • sass 1.69.7
  • vite 5.0.11
  • @babel/core 7.23.7
  • @types/node 20.11.3
  • @types/react 18.2.48
  • @types/react-dom 18.2.18
  • eslint 8.56.0
  • typescript 5.3.3
src/frontend/package.json
  • @changesets/cli 2.27.1
  • prettier 3.2.2
  • turbo 1.11.3
  • node >=16.0.0
  • yarn 1.22.21
src/frontend/packages/core/package.json
  • @openfun/cunningham-react 2.4.0
  • @tanstack/react-query 5.17.12
  • @tanstack/react-query-devtools 5.17.12
  • axios 1.6.5
  • classnames 2.5.1
  • dayjs 1.11.10
  • echarts 5.4.3
  • echarts-for-react 3.0.2
  • lodash.clonedeep 4.5.0
  • react 18.2.0
  • react-error-boundary 4.0.13
  • react-top-loading-bar 2.3.1
  • @types/lodash.clonedeep 4.5.9
  • @types/react 18.2.48
  • esbuild-sass-plugin 3.1.0
  • eslint 8.56.0
  • typescript 5.3.3
  • tsup 8.0.1
src/frontend/packages/eslint-config-custom/package.json
  • @typescript-eslint/eslint-plugin 6.19.0
  • @typescript-eslint/parser 6.19.0
  • eslint 8.56.0
  • eslint-config-airbnb 19.0.4
  • eslint-config-airbnb-typescript 17.1.0
  • eslint-config-next 14.0.4
  • eslint-config-prettier 9.1.0
  • eslint-import-resolver-typescript 3.6.1
  • eslint-import-resolver-webpack 0.13.8
  • eslint-plugin-compat 4.2.0
  • eslint-plugin-formatjs 4.12.0
  • eslint-plugin-import 2.29.1
  • eslint-plugin-jsx-a11y 6.8.0
  • eslint-plugin-prettier 5.1.3
  • eslint-plugin-react 7.33.2
  • eslint-plugin-react-hooks 4.6.0
src/frontend/packages/tsconfig/package.json
src/frontend/packages/video/package.json
  • @openfun/cunningham-react 2.4.0
  • @tanstack/react-query 5.17.12
  • @tanstack/react-query-devtools 5.17.12
  • axios 1.6.5
  • classnames 2.5.1
  • dayjs 1.11.10
  • echarts 5.4.3
  • echarts-for-react 3.0.2
  • lodash.clonedeep 4.5.0
  • react 18.2.0
  • react-top-loading-bar 2.3.1
  • @types/lodash.clonedeep 4.5.9
  • @types/react 18.2.47
  • esbuild-sass-plugin 3.1.0
  • eslint 8.56.0
  • typescript 5.3.3
  • tsup 8.0.1
pep621
docs/pyproject.toml
  • mike ==2.0.0
  • mkdocs-material ==9.5.19
  • mkdocs ==1.6.0
  • neoteroi-mkdocs ==1.0.5
  • pymdown-extensions ==10.8.1
  • setuptools >=61.0
src/api/core/pyproject.toml
  • alembic ==1.13.1
  • arrow ==1.3.0
  • click ==8.1.7
  • django-lti-toolbox ==1.3.0
  • fastapi ==0.110.2
  • importlib-metadata ==7.1.0
  • pandas ==2.2.2
  • psycopg2-binary ==2.9.9
  • python-jose ==3.3.0
  • rfc3987 ==1.3.8
  • sentry-sdk ==2.0.1
  • sqlmodel ==0.0.16
  • uvicorn ==0.29.0
  • ralph-malph ==4.2.0
  • dev/black ==24.4.2
  • dev/build ==1.2.1
  • dev/freezegun ==1.5.0
  • dev/ipdb ==0.13.13
  • dev/polyfactory ==2.15.0
  • dev/pytest-cov ==5.0.0
  • dev/ruff ==0.4.2
  • dev/mypy ==1.10.0
  • dev/pandas-stubs ==2.2.1.240316
  • dev/types-python-jose ==3.3.4.20240106
  • ci/twine ==5.0.0
  • setuptools >=61.0
src/api/plugins/video/pyproject.toml
  • setuptools >=61.0
src/app/pyproject.toml
  • django-configurations ==2.5.1
  • django-cors-headers ==4.3.1
  • django-lti-toolbox ==1.3.0
  • djangorestframework_simplejwt ==5.3.1
  • dockerflow ==2024.4.2
  • gunicorn ==22.0.0
  • oauthlib ==3.2.2
  • psycopg2-binary ==2.9.9
  • sentry-sdk ==2.0.1
  • urllib3 ==2.2.1
  • whitenoise ==6.6.0
  • dev/black ==24.4.2
  • dev/build ==1.2.1
  • dev/factory-boy ==3.3.0
  • dev/Faker ==24.14.1
  • dev/ipdb ==0.13.13
  • dev/pytest-cov ==5.0.0
  • dev/pytest-django ==4.8.0
  • dev/ruff ==0.4.2
  • dev/xmltodict ==0.13.0
  • ci/twine ==5.0.0
  • setuptools >=61.0

  • Check this box to trigger a request for Renovate to run again on this repository

👷(backend) Add a pre commit hook to enforce strict checks at commit time instead of relying on the make commands and the ci

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
Today we lint our code using manual make commands and automatic ci steps.
It often happens to commit unlinted code that will fail in the pipeline, and it can be a waste of time.

Describe the solution you'd like
To prevent this, we could setup a precommit hook that will automatically lint and fix our code at commit time.
It is especially relevant if we add ruff to the codebase (see #23)
We could use black and ruff in the pre commit hook. Regarding mypy (if we implement it : see #25), it can be done but we should decide if we want to endure the time penalty it takes on every commit.
We could also add the gitlint to the hook

A base config could be the fastapi pre commit config file

Discovery, Documentation, Adoption, Migration Strategy
Pre commit hooks are standard git scripts but we should use the pre commit library to make hooks manageable and versionable.

Do you want to work on it through a Pull Request?
Yes

API should return a 404 error to indicate that the requested resource was not found

Bug Report

Expected behavior/code
If a video doesn't exist in the LRS endpoints, the API should return a 404 error to indicate that the requested resource was not found.

Actual Behavior
When querying the API with an invalid ID, the API returns a 200 response, which is misleading since it implies that the request was successful even though the resource does not exist.

Steps to Reproduce

  1. Query API route /api/v1/video/uuid://fake-uuid/downloads
  2. Read response's status code.

Environment

  • Ralph version: 3.8

Possible Solution

When a request with an invalid ID is received, the API should be modified to return a 404 (Not Found) error, indicating that the video resource does not exist. This check would use future elements from Ralph related to some current works on activities. Once Ralph provides a method to verify resource existence, consider consolidating Warren's API.

Additional context/Screenshots
None.

Pin frontend dependencies

Bug Report

All package dependencies should be pinned. Please update all package.json files from the frontend web app and the three packages.

Issue: preprocessing statements doesn't support timezone

Bug Report

Expected behavior/code
When querying the view API with the parameters /views?since=2023-10-12T00:00:00+02:00&until=2023-10-12T23:59:59+02:00, the expected behavior is to receive daily counts only for the date 2023-10-12.

Actual Behavior

It's not the case.

The issue arises during the conversion of statement timestamps to date strings, leading to incorrect daily counts. We fail to account for the timestamps' initial UTC offset, resulting in daily counts from the day before or after.

Possible Solution
To fix this, we should first convert statement timestamps with consideration for their initial UTC offset before converting them to date strings. This ensures accurate daily counts aligned with the specified date.

Openapi schema failing to load

Bug Report

Expected behavior/code
Have the http://localhost:8100/api/v1/docs swagger docs display correctly locally.

Actual Behavior
The endpoint displays an error
image

Backend error : "ValueError: Value not declarable with JSON Schema, field: name='day' type=Date required=True"

A clear and concise description of the behavior.

  1. make run
  2. Go to http://localhost:8100/api/v1/docs

Environment

Possible Solution
Probably cause by

class VideoDayViews(BaseModel):
    """Model to represent video views for a date."""

    day: Date
    views: int = 0

We probably need to make Date compatible with openapi.

Overcome `react-echart` limitations

Expected behavior

Support all kind of series' updates in echart plots:

  • Series addition.
  • Series updates.
  • Series deletion.

Actual behavior

Supported series' updates in echart plots:

  • Series addition.
  • Series updates.

Problem description

Series deletion is not supported due to react-echart third-party limitations. An issue is opened since 2022. For details, see here.

Partial echartInstances.setOption method's parameters are supported in react-echart mapping. Refer to the method documentation for more details.

echartInstances.setOption accepts either :
parameters

(option: Object, notMerge?: boolean, lazyUpdate?: boolean)

or

(option: Object, opts?: {
    notMerge?: boolean;
    replaceMerge?: string | string[];
    lazyUpdate?: boolean;
})

As the official documentation explains :

There are two ways to remove components:
Totally removal: use notMerge: true, all of the components will be removed.
Partially removal: use replaceMerge: [...], the specified types of components will be removed if no id matched. This mode is useful to keep the state (e.g., highlight / animation / selected area) of the other components while make removal.

Unfortunately, the react-echart library currently lacks support for the replaceMerge parameter. You can check the component internal logic and component props for further details.

This means that when updating options in react-echart, there won't be a merging of the new options with the existing ones. Instead, the update will occur without merging, which could trigger animations and color changes.

Proposal

To overcome react-echart limitations, a better approach is creating a custom echart mapping. This empowers us to address specific needs, enhance flexibility, and gain greater control over the chart functionalities in our application.

Add a security mechanism to the Content-Item Selection flow

Feature Request

LTISelectView receives an LTI request and verify it, then passes its data to the frontend. The frontend returns back the selection to the LTIRespondView view. This last view has no way to verify frontend data authenticity and origins.

  • Wait for #86 to be merged.
  • Create a new access token class.
  • Encode and sign lti_select_form_data before passing it to the frontend.
  • Decode and verify signature of the payload received by the LTIRespondView.

[Experience Index] Make XI extensible by implementing plugin support

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
Experience Index only supports indexing courses and content from Moodle.

Describe the solution you'd like
A plugin architecture for the XI indexers would be nice, with a discovery mechanism. XI CLI commands should also support this plugin architecture.

✨(backend) Add a downloads endpoint to the video plugin returning time series of downloads for a specific video

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
Add a downloads endpoint to the video plugin to get a time series representing the downloads of a specific video

Describe the solution you'd like
Introduce the following endpoint : /video/<video_id>/downloads
that would query the lrs using the http://id.tincanapi.com/verb/downloaded xAPI verb

Do you want to work on it through a Pull Request?
Yes

🧱(backend) Distributing warren docker images

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
We should think about docker images distribution for warren so that teams can deploy warren without hassle.
We should consider the case of plugins. Should we have two separate docker images or just 2 different tags ? or maybe a tag per plugin ?

Describe the solution you'd like
The actual Dockerfile defines 2 stages : production with only the core and development that comprises core, plugins and dev dependencies.
We could add a 3rd stage named e.g. 'full' that comprises core and plugins without dev dependencies and users would be able to pull either fundocker/warren:core or fundocker/warren:full.
It's simple.

Describe alternatives you've considered
Please add your alternatives in the comments section :)
We could probably build instead two images, let's say fundocker/warren and fundocker/warren-full, as it's done with multiple fundocker images (marsha, funmooc ..). We could still use the same Dockerfile with multiple tag and just push two different images I suppose.

Discovery, Documentation, Adoption, Migration Strategy
Users will be able to docker pull fundocker/warren:core and docker pull fundocker/warren:full

Do you want to work on it through a Pull Request?
I could definitely work on this, let's see about that later.

Missing tests for Warren core models

Purpose

Models used for statements daily aggregations in indicators are implemented but not tested. Tests for the models methods can be implemented to improve code consistency and get a quicker start up for new code contributors.

Proposal

Add tests for Warren core DailyCount and DailyCounts models and enrich methods docstrings with examples.

👷(backend) Use astral-sh/ruff to make linting faster and simpler

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
It would be nice to make the lint tasks in the ci and the Makefile be simpler and faster by introducing ruff

Describe the solution you'd like
Introduce ruff and use it to replace isort, flake8, pycodestyle and bandit.
we would keep ruff, black and mypy as recommended by fastapi creator.

Discovery, Documentation, Adoption, Migration Strategy
Check out the ruff readme. We'll use the ruff check command and configure the tool in core/pyproject.toml

Do you want to work on it through a Pull Request?
Yes.

👷(backend) Add mypy to the ci and correct violations in the codebase

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
We could introduce mypy as a way to make our ci lint checks stronger and check and enforce strict typing in the codebase

Describe the solution you'd like
Install mypy in the devdependencies, add a lint-mypy makefile command and a step to the ci that runs mypy on the code

Describe alternatives you've considered
Some other type checkers exist and are popular like pyright or pyre but mypy is still the most standard choice.

Discovery, Documentation, Adoption, Migration Strategy
Users will be able to make lint-mypy and mypy will run automatically in the ci

Do you want to work on it through a Pull Request?
Yes

[API] Elasticsearch should'nt be a direct dependency

Bug Report

Expected behavior/code
Warren's API no longer relies on Elasticsearch, it should not be a direct dependency.

Actual Behavior
Removing Elasticsearch dependency on the API service crashes the server.

Environment

  • Ralph version: at least 3.8+

Possible Solution
Wait for a new Ralph release that fixes this issue (e.g. v4.0.0 🤞)

Add API health checks à-la-mozilla

Purpose

When deploying an application to Kubernetes, this application should be able to give insights about its health status. The standard way to achieve this for an HTTP server is to implement two endpoints responding to readiness and liveness probes.

Proposal

Similarly to Ralph, we can implement à-la-mozilla /__heartbeat__ and /__lbheartbeat__ routes in a dedicated health router.

The heartbeat should check that the server can reach the postgresql database and configured LRS.

[Experience Index] Soft delete experiences and relations

Feature Request

Is your feature request related to a problem or unsupported use case? Please describe.
Have a way to softly delete LOM and their relations.

Describe the solution you'd like
Add an endpoint in the experience index API, that archive experiences.
Implement missing feature in the Experience and Relation clients.

Might be necessary to implement the meta-data and lifecycle parts of LOM data modeling to track the life of a LOM object.

[Swagger/OpenAPI] JWT token missing from documentation

Bug Report

Expected behavior/code
A JWT token (forged from the LTI token) is required on API endpoints to secure the API, and potentially retrieve informations about the course or the user.
This token should appear in the Swagger UI documentation at http://localhost:8100/api/v1/docs

Actual Behavior
This required token does not appear in the Swagger UI documentation.
When reading the FastAPI documentation, and the utils function that is injected to the endpoint, the token should be appearing on the OpenAPI doc, but it does not.

Environment

  • Warren version: 0.2.0

Additional context/Screenshots
image

Handle refresh token expiration

Bug Report

Expected behavior/code
When the refresh token is expired, ask the user to log in again or refresh the page.

Actual Behavior
Nothing happen.

Steps to Reproduce

  1. Change refresh token lifetime to a short value.
  2. Load frontend, and wait for it to expire.

Possible Solution
Show a pop-in and disable all dashboard functionalities.

Offer an LTI icon for Warren external tool

Feature Request

LMS include a feature to render an icon for an external tool. This visual representation simplifies navigation and enhances the user experience, making it easier for educators, administrators, and students to access Warren's educational tools within the system.

  • Design a basic Icon that represents analytics
  • Add it to the Django static files
  • Set its URL properly in the LTI configuration XML file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.