Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web dashboard #613

Merged
merged 5 commits into from
Apr 11, 2024
Merged

Conversation

KIRA009
Copy link
Contributor

@KIRA009 KIRA009 commented Mar 23, 2024

What kind of change does this PR introduce?

This PR adds a web dashboard to the tray. The tray now contains a 'Launch dashboard' option, clicking on which will start a nextjs server at port 3000, and a fastapi server at 8000. A new browser tab will be opened with the nextjs app url. On exiting the tray, the servers are gracefully shutdown.

To complete the initial setup, see the changes to the Manual Setup section in README.md

Summary

Checklist

  • My code follows the style guidelines of OpenAdapt
  • I have performed a self-review of my code
  • If applicable, I have added tests to prove my fix is functional/effective
  • I have linted my code locally prior to submission
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (e.g. README.md, requirements.txt)
  • New and existing unit tests pass locally with my changes

How can your code be run and tested?

To complete the initial setup, see the changes to the Manual Setup section in README.md

Screenshot image
Screen recoding [Google drive link](https://drive.google.com/file/d/18L3tR2IHKlRvU2XICfMphomd8-dQm-am/view?usp=drive_link)

@KIRA009 KIRA009 marked this pull request as draft March 23, 2024 19:02
Copy link
Member

@abrichr abrichr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the great start @KIRA009 !

Code looks good other than a few small comments. Initially I was unable to install it:

(openadapt-py3.10) abrichr@MacBook-Pro-4 OpenAdapt % cd openadapt/app/dashboard
(openadapt-py3.10) abrichr@MacBook-Pro-4 dashboard % nvm use
Found '/Users/abrichr/oa/src/OpenAdapt/openadapt/app/dashboard/.nvmrc' with version <21>
N/A: version "21 -> N/A" is not yet installed.

You need to run "nvm install 21" to install it before using it.
(openadapt-py3.10) abrichr@MacBook-Pro-4 dashboard % 

May be worth adding this to the README:

nvm install 21

As mentioned in a comment, ideally these would get executed automatically as part of the main project poetry install.

Also, since I had another project running on port 3000:

2024-03-23 15:20:42.823 | INFO     | openadapt.config:<module>:269 - active_branch_name='feature/web-dashboard-setup'
2024-03-23 15:20:42.824 | INFO     | openadapt.config:<module>:271 - is_reporting_branch=False

> [email protected] dev
> concurrently "npm run next-dev" "npm run fastapi-dev"

[1] 
[1] > [email protected] fastapi-dev
[1] > python3 -m uvicorn api.index:app --reload
[1] 
[0] 
[0] > [email protected] next-dev
[0] > next dev
[0] 
[1] INFO:     Will watch for changes in these directories: ['/Users/abrichr/oa/src/OpenAdapt/openadapt/app/dashboard']
[1] INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
[1] INFO:     Started reloader process [4696] using WatchFiles
[0]  ⚠ Port 3000 is in use, trying 3001 instead.
[0]    ▲ Next.js 14.1.4
[0]    - Local:        http://localhost:3001
[0] 
[1] INFO:     Started server process [4698]
[1] INFO:     Waiting for application startup.
[1] INFO:     Application startup complete.
[0]  ✓ Ready in 7.9s

The tab that opened in Chrome opened to http://localhost:3000/ , however. I think we need to be able to determine the url programmatically. What do you think?


@app.get("/api/python")
def hello_world():
return {"message": "Hello World"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abrichr
Copy link
Member

abrichr commented Mar 23, 2024

Please also add screenshots to your PR description! 🙏

@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch 2 times, most recently from 75086c8 to 9af81f6 Compare March 23, 2024 21:38
@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch from 9af81f6 to 06c6f76 Compare March 23, 2024 21:47
README.md Outdated
cd openadapt/app/dashboard
nvm install 21
nvm use
npm install
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally all of this would be automated.

What do you think about something like this: https://stackoverflow.com/a/73649412

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

./entrypoint.sh: line 3: nvm: command not found
./entrypoint.sh: line 4: nvm: command not found
# __init__.py
import os
import subprocess


def _run(bash_script):
    return subprocess.call(bash_script, shell=True)

def entrypoint():
    cwd = os.path.dirname(os.path.realpath(__file__))
    os.chdir(cwd)
    return _run(f"source ./entrypoint.sh")
# entrypoint.sh

#!/bin/bash
nvm install 21
nvm use
npm install

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Via ChatGPT:

#!/bin/bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

nvm install 21
nvm use 21  # Specify the version to ensure it uses the right one
npm install

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also install npm and nvm in the installation scripts, and update the manual installation steps in the README to include this as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added on cfba059

@abrichr
Copy link
Member

abrichr commented Mar 26, 2024

To get this merged:

  • remove "Home" and default to Recordings
  • link/button hover cursor style
  • fix timestamp
  • fix bug when stopping a recording (or refreshing after creating a recording?):
[1]   File "/Users/abrichr/oa/src/OpenAdapt/openadapt/app/dashboard/api/index.py", line 27, in get_recordings                                                                                                                                             
[1]     recordings = get_all_recordings()                                                                                                                                                                                                                 
[1]   File "/Users/abrichr/oa/src/OpenAdapt/openadapt/app/dashboard/api/index.py", line 21, in get_all_recordings                                                                                                                                         
[1]     return db.query(Recording).order_by(sa.desc(Recording.timestamp)).all()                                                                                                                                                                           
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 2772, in all                                                                                         
[1]     return self._iter().all()                                                                                                                                                                                                                         
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/orm/query.py", line 2915, in _iter                                                                                       
[1]     result = self.session.execute(                                                                                       
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1714, in execute                                                                                   
[1]     result = conn._execute_20(statement, params or {}, execution_options)                                                                                                                                                                             
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1705, in _execute_20                                                                               
[1]     return meth(self, args_10style, kwargs_10style, execution_options)                                 
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/sql/elements.py", line 333, in _execute_on_connection                                                                    
[1]     return connection._execute_clauseelement(                                                                                                                                                                                                         
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1572, in _execute_clauseelement                                                                    
[1]     ret = self._execute_context(                                                                                                                                                                                                                      
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1806, in _execute_context                                                                          
[1]     self._handle_dbapi_exception(                                                                                                                                                                                                                     
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2124, in _handle_dbapi_exception                                                                   
[1]     util.raise_(                                                                                                                                                                                                                                      
  File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/util/compat.py", line 208, in raise_                                                                                         
[1]     raise exception                                                                                                                                                                                                                                   
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1800, in _execute_context                                                                          
[1]     context = constructor(                                                                                                                                                                                                                            
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1020, in _init_compiled
[1]     self.cursor = self.create_cursor()                                                                                   
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1391, in create_cursor
[1]     return self.create_default_cursor()                                                                                                                                                                                                               
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 1394, in create_default_cursor                                                                  
[1]     return self._dbapi_connection.cursor()                                                                                                                                                                                                            
[1]   File "/Users/abrichr/Library/Caches/pypoetry/virtualenvs/openadapt-4aqHBuvC-py3.10/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 1111, in cursor
[1]     return self.dbapi_connection.cursor(*args, **kwargs)                                                                                                                                                                                              
[1] sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 13071364096 and this is thread id 13088153600.                               
[1] [SQL: SELECT recording.id AS recording_id, recording.timestamp AS recording_timestamp, recording.monitor_width AS recording_monitor_width, recording.monitor_height AS recording_monitor_height, recording.double_click_interval_seconds AS recording_
double_click_interval_seconds, recording.double_click_distance_pixels AS recording_double_click_distance_pixels, recording.platform AS recording_platform, recording.task_description AS recording_task_description, recording.video_start_time AS recordi
ng_video_start_time  

@KIRA009 KIRA009 marked this pull request as ready for review March 29, 2024 09:09
@abrichr abrichr changed the title [DRAFT] Web dashboard Web dashboard Apr 1, 2024
@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch from 1750f78 to cfba059 Compare April 2, 2024 07:12
README.md Outdated
@@ -96,6 +96,8 @@ pip3 install poetry
poetry install
poetry shell
alembic upgrade head
poetry run dashbaord
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This command installs the npm packages, so I figured we should add it in the installation phase

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to install the npm packages as part of poetry install?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem to be the case 🤔

@abrichr
Copy link
Member

abrichr commented Apr 8, 2024

@KIRA009 can you please also look into why the build is failing? https://github.com/OpenAdaptAI/OpenAdapt/pull/613/checks

@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch 2 times, most recently from fef417a to d8e4df7 Compare April 9, 2024 06:27
@KIRA009
Copy link
Contributor Author

KIRA009 commented Apr 9, 2024

The CI fail seems really baffling. black should be installed when running poetry install --no-interaction --no-root, but in the CI fail I saw that this step was being skipped because of a cache condition. I commented out that condition and it still got skipped. I commented out the cache step, but it still seems to be running it - https://github.com/OpenAdaptAI/OpenAdapt/actions/runs/8611306500/workflow?pr=613

@abrichr
Copy link
Member

abrichr commented Apr 10, 2024

Via ChatGPT:


The issue here is with the Continuous Integration (CI) setup on GitHub Actions, specifically related to caching and the environment setup for running black, a Python code formatter.

  1. Caching Issue: The GitHub Actions workflow is designed to cache dependencies to speed up the CI process. However, caching can sometimes lead to issues where updates or changes in the environment are not picked up because the cache is used instead of creating a new environment.

  2. Virtual Environment Issue: The error message indicates that the virtual environment where black is supposed to be installed is either not activated properly or black is not installed in the expected environment. This is corroborated by the error "Command not found: black".

  3. Skipped Steps: If the step to install dependencies (poetry install --no-interaction --no-root) is being skipped even after removing cache conditions, it suggests there may be a misconfiguration in the GitHub Actions workflow file. This could be due to conditions set in the workflow that are not met or due to GitHub Actions not properly recognizing changes to the workflow file.

Solutions

  1. Explicitly Install black Before Use: As a quick workaround, you could explicitly install black before running it to ensure it's available. For example:

    - name: Install Black
      run: poetry run pip install black

    This ensures black is installed in the poetry managed environment.

  2. Fix Caching Logic: Review the caching logic in the GitHub Actions workflow. Make sure the cache key changes when dependencies change. This can be done by including a hash of the poetry.lock file in the cache key.

  3. Ensure Workflow Steps Run as Expected: If steps are being skipped unexpectedly, review the conditions that control these steps. Ensure there's no issue with the way conditions are evaluated. If necessary, temporarily remove conditional checks to debug the issue.

  4. Review and Test Workflow Changes: If changes to the workflow are not being picked up, make sure you're editing the correct file and branch that the CI is running against. Sometimes, workflow changes need to be merged into the main branch (or the branch against which the PR is made) before they are picked up by GitHub Actions.

  5. Manual Activation of the Virtual Environment: If the virtual environment does not seem to be activated correctly, you could explicitly source the activation script as a step in the workflow before running any Python commands:

    - name: Activate virtual environment
      run: source .venv/bin/activate

Review and adjust the GitHub Actions workflow file based on these suggestions to resolve the CI failure.

@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch 4 times, most recently from c3a7fa2 to 8285e25 Compare April 11, 2024 18:27
@KIRA009 KIRA009 force-pushed the feature/web-dashboard-setup branch from 74ae8c8 to 23bd7d3 Compare April 11, 2024 19:03
Copy link
Member

@abrichr abrichr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@abrichr abrichr merged commit 0050cea into OpenAdaptAI:main Apr 11, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants