Evaluation
Summary of achievements
Achievements table
ID | Requirements | Priority | State | Contributors |
---|---|---|---|---|
1 | A closed authentication / login system where clinicians have download access and data scientists have download and upload access. | Must | Completed | Gabriel, Jeffrey |
2 | Upload of trained machine learning models which are dockerised | Must | Completed | Gabriel, Jeffrey, Laasya |
3 | Docker images can be downloaded and run locally with a provided frontend, allowing users to make predictions. | Must | Completed | Gabriel, Jeffrey, Laasya |
4 | Upload of datasets as zips | Must | Completed | Gabriel, Jeffrey |
5 | Download of datasets as zips | Must | Completed | Gabriel, Jeffrey |
6 | Functioning deployment onto Linode | Must | Completed | Gabriel |
7 | Administrative user type which can create new users | Should | Completed | Gabriel, Jeffrey |
8 | Delete uploaded models | Should | Completed | Gabriel, Jeffrey |
9 | Delete uploaded datasets | Should | Completed | Gabriel, Jeffrey |
10 | Search for datasets / models through a search bar | Should | Completed | Jeffrey |
11 | Private dashboard to view the users own uploaded datasets and models | Should | Completed | Jeffrey |
12 | Upload results / feedback onto the platform | Could | Completed | Gabriel, Jeffrey |
13 | Records of model downloads stored to prompt users to give feedback | Could | Completed | Gabriel |
Functionality | Completion |
---|---|
Key functionalities | 100% |
Optional functionalities | 100% |
Individual contribution table
Work Packages | Gabriel | Jeffrey | Laasya |
---|---|---|---|
Project Partners liaison | 33% | 33% | 34% |
HCI | 33% | 33% | 34% |
Research and experiments | 60% | 20% | 20% |
System Architecture | 100% | 0 | 0 |
Database design & implementation | 100% | 0 | 0 |
Backend | 95% | 0 | 5% |
API | 100% | 0 | 0 |
UI Design | 15% | 70% | 15% |
UI Design Implementation | 0 | 100% | 0 |
Frontend | 0 | 100% | 0 |
Unit and system tests | 100% | 0 | 0 |
end-to-end tests | 0 | 100% | 0 |
Deployment and Linode management | 100% | 0 | 0 |
User acceptance testing | 34% | 33% | 33% |
Report Website | 33% | 33% | 34% |
Video Editing | 0 | 0 | 100% |
Overall contribution | 43% | 33% | 24% |
Main roles | Backend | Frontend | Backend, Integration |
Critical evaluation of the project
User Experience
When designing the user interface, we have always taken the ease of usage and the overall user experience as our top priority. We have also tried really hard in making our UI as responsive as possible for laptop and desktop devices.
- Clean, responsive interfaces with minimalistic design, and easy to use interactive components in the navigation bar.
- Popups menus containing meaningful messages in response of user actions such as successful uploads and also for alerting users about unacceptable actions such as uploading file of invalid types
- Loading screen spinners and progress bars which informs user about what is happening behind the scenes of the UI
- Very interactive interface with user action feedback in the form of animations of UI components
- Minimal user action required, takes on average 2 clicks to access any desired part of the web application.
And more...
For more information, please checkout our UX testing section and our demo video.
Functionality
We believe what we have managed to achieve functionality wise is excellent, we have implemented everything our client wanted us to implement, and his requirements were not trivial. He is very impressed in what we have managed to achieve.
The functionality is there, but this system is a prototype, and it’s not perfect. There is no automated CI. Building docker images is not done asynchronously, and the system is unusable during these 1-minute or so build times. The model upload is restrictive as there is only one ‘predict’ endpoint, and it must take a file as input and JSON as output. Models are not tested, and in theory could do absolutely nothing when run by a downloader.
Stability
We have done well to provide a stable service. We put a lot of effort into testing, with full end-to-end tests, and system and unit testing for the backend. We are confident in our systems stability during development and production. User testing proved this as we did not find any major bugs. To improve this, the first thing to do would be to set up CI.
Efficiency
As mentioned before, build times are slow and the system is unusable during this time, but we did everything we could to reduce image sizes and build times, such as splitting the frontend and backend into separate images, having the frontend image pre-built, and optimising the model Dockerfile as much as possible. We also went with FastAPI to make the application lightweight and more efficient than if we were to use something like Django. Though again, what we have is not perfect, and I think asynchronous builds and database connections could seriously improve the efficiency of the backend.
Compatibility
All functionality works on Windows, MacOS, and Linux as well as ARM64 and AMD64 architectures, which we proved through user testing. We did not test the system on Tablets or Smart Phones and the frontend hasn't been designed for mobile devices, as this system is not targeted to be used by these devices. It is primarily for upload and download of docker images. However, we worked hard to make our UI responsive, and tested it with multiple different laptops and monitors with different resolutions and aspect ratios
Maintainability
We believe with maintainability we excelled. We have a full testing suit with system, unit, and end-to-end tests. We use tools like alembic for database migrations, the API is heavily documented and abstracted. We heavily documented implementation on the website, wrote a step-by-step deployment manual and we used dockerised deployment, making our system extremely portable. I think the biggest flaw that could be improved upon for maintainability is to introduce automatic CI that runs our testing suit for each PR.
Project management
For project management we did rather well, we started our project early and consistently worked on it from the beggining rather than doing everything at the end. We would have weekly sprints on teams aswell as weekly standups with our client. We used Trello to manage progress and used agile methodology throughout development (scrums, standups). We stayed in touch almost daily over telegram.
To assure code quality, all new features or bug fixes were written on a new branch, once implemented, the author must create a PR which required at least one other member to approve. This encouraged us to write code to a high standard.
Future work
There are so many things I would have loved to have done if we had more time.
Currently, before each PR to the backend, one must run the system tests locally, if all tests pass, we go ahead with the pull request. Obviously, this is not an optimal solution. If we had more time, I would have loved to have set up automated CI with something like GitHub Actions, Jenkins, or Travis. But since our backend image requires docker in docker, it makes it not so trivial to set up, and in the time frame we settled for this solution.
In our current implementation, building docker images is not done asynchronously, and the user cannot make other requests during these builds which take around a minute. This is probably one of the biggest draw backs with our implementation. If I had more time, I would love to have set up a separate docker container which only handles building images. This would be done asynchronously, and I would use Celery to handle and queue requests to this service. This would allow the user to continue using the other aspects of our application whilst the image is being built, and then they can check back later when it is up.
Our current solution only allows one ‘predict’ endpoint for machine learning models, and it must take in a file as input and give output as JSON. This is somewhat flexible as the files can contain anything the developer wants, including extra parameters in a separate JSON file of a zip for example. The developer just specifies this input when uploading a model. The JSON output can have any number of key, value pairs. This however is restrictive; I would love to have implemented auto generation of model endpoints with a tool like mako which autogenerates python code. This way the user could specify any number of endpoints (predict, fit, train) and add any input and output parameters. You would need to autogenerate endpoints, and have an endpoint which returned all endpoints, and then you would need dynamic generation of endpoint interfaces in the model UI. This would be an interesting task for future systems engineering groups.
Another drawback of our solution is that in theory the model-uploader could upload source code, requirements, and config files with complete gibberish and the model would still be able to be uploaded, downloaded, and ran. The frontend would still provide a predict button which wouldn’t do anything when clicked with an uploaded file. If I had more time, I would have loved to have set up some form of asynchronous testing in a separate docker image, that spins up these docker images briefly and tests that they get a response from the predict function, if not, we send an error message to the user and ask them to reupload. also, we could test syntax of config files directly on upload.