mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 12:40:35 +00:00
Merge pull request #4237 from OpenBB-finance/release/2.4.0
Release 2.4.0
This commit is contained in:
1
.dockerignore
vendored
1
.dockerignore
vendored
@@ -8,5 +8,4 @@ Dockerfile*
|
||||
.idea
|
||||
__pycache__
|
||||
.python-version
|
||||
jupyterlab/*/node_modules
|
||||
logs/
|
||||
|
||||
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -19,10 +19,11 @@
|
||||
|
||||
# Checklist:
|
||||
|
||||
- [ ] Update [our Hugo documentation](https://openbb-finance.github.io/OpenBBTerminal/) following [these guidelines](https://github.com/OpenBB-finance/OpenBBTerminal/tree/main/website).
|
||||
- [ ] I have adhered to the GitFlow naming convention and my branch name is in the format of `feature/feature-name` or `hotfix/hotfix-name`.
|
||||
- [ ] Update [our documentation](https://openbb-finance.github.io/OpenBBTerminal/) following [these guidelines](https://github.com/OpenBB-finance/OpenBBTerminal/tree/main/website). Update any user guides that are affected by the changes.
|
||||
- [ ] Update our tests following [these guidelines](https://github.com/OpenBB-finance/OpenBBTerminal/tree/main/tests).
|
||||
- [ ] Make sure you are following our [CONTRIBUTING guidelines](https://github.com/OpenBB-finance/OpenBBTerminal/blob/main/CONTRIBUTING.md).
|
||||
- [ ] If a feature was added make sure to add it to the corresponding [scripts file](https://github.com/OpenBB-finance/OpenBBTerminal/tree/main/scripts).
|
||||
- [ ] If a feature was added make sure to add it to the corresponding [integration test script](https://github.com/OpenBB-finance/OpenBBTerminal/tree/develop/openbb_terminal/miscellaneous/integration_tests_scripts).
|
||||
|
||||
|
||||
# Others
|
||||
|
||||
18
.github/release-drafter.yml
vendored
18
.github/release-drafter.yml
vendored
@@ -1,10 +1,28 @@
|
||||
name-template: 'OpenBB Terminal v$NEXT_MINOR_VERSION'
|
||||
tag-template: 'v$NEXT_MINOR_VERSION'
|
||||
exclude-contributors:
|
||||
- 'jmaslek'
|
||||
- 'DidierRLopes'
|
||||
- 'JerBouma'
|
||||
- 'deeleeramone'
|
||||
- 'hjoaquim'
|
||||
- 'jose-donato'
|
||||
- 'luqman-bello'
|
||||
- 'martinb-bb'
|
||||
- 'montezdesousa'
|
||||
- 'tehcoderer'
|
||||
- 'Chavithra'
|
||||
- 'colin99d'
|
||||
- 'northern-64bit'
|
||||
- 'piiq'
|
||||
- 'andrewkenreich'
|
||||
|
||||
template: |
|
||||
## Thank you and welcome to our new contributors 🔥
|
||||
$CONTRIBUTORS
|
||||
|
||||
## What's new 🎉
|
||||
|
||||
## What's changed 🚀
|
||||
$CHANGES
|
||||
|
||||
|
||||
244
.github/workflows/README.md
vendored
Normal file
244
.github/workflows/README.md
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
# OpenBB Workflows
|
||||
This directory contains the workflows for the OpenBB 🦋 Project. The workflows are:
|
||||
|
||||
| Workflows | Summary
|
||||
| :-------------------- |:---
|
||||
| branch-name-check.yml | Checks if the branch name is valid and follows the naming convention.
|
||||
| build-release.yml | Builds the project and runs the tests.
|
||||
| docker.yml | Builds the docker image and pushes it to the docker hub.
|
||||
| draft.yml | Creates a draft release when a new tag is pushed.
|
||||
| gh-pages.yml | Builds the documentation and deploy to github pages.
|
||||
| integration-test.yml | Runs the integration tests.
|
||||
| intel_macos_build.yml | Builds the project on Intel Macs.
|
||||
| issue.yml | Creates an issue when a new bug is reported.
|
||||
| labels.yml | Adds labels to the issues and pull requests.
|
||||
| linting.yml | Runs the linters.
|
||||
| m1_macos_build.yml | Builds the project on M1 Macs.
|
||||
| mac.yml | Builds the project on Mac OS X Full Clean Build with ML.
|
||||
| nightly-build.yml | Builds the project and runs the integration tests every night on the `develop` branch.
|
||||
| pypi.yml | Publishes the package to PyPI.
|
||||
| unit-test.yml | Runs the unit tests.
|
||||
| windows.yml | Builds the project on Windows 10 Full Clean Build with ML.
|
||||
| windows10_build.yml | Builds the project on Windows 10.
|
||||
|
||||
## Branch Name Check Workflow
|
||||
Objective: To check if pull request branch names follow the GitFlow naming convention before merging.
|
||||
|
||||
Triggered by: A pull request event where the target branch is either develop or main.
|
||||
|
||||
Branches checked: The source branch of a pull request and the target branch of a pull request.
|
||||
|
||||
Steps:
|
||||
|
||||
1. Extract branch names: Using the jq tool, the source and target branch names are extracted from the pull request event. The branch names are then stored in environment variables and printed as output.
|
||||
|
||||
2. Show Output result for source-branch and target-branch: The source and target branch names are printed to the console.
|
||||
|
||||
3. Check branch name for develop PRs: If the target branch is develop, then the source branch is checked against a regular expression to ensure that it follows the GitFlow naming convention. If the branch name is invalid, a message is printed to the console and the workflow exits with a status code of 1.
|
||||
|
||||
4. Check branch name for main PRs: If the target branch is main, then the source branch is checked against a regular expression to ensure that it is either a hotfix or a release branch. If the branch name is invalid, a message is printed to the console and the workflow exits with a status code of 1.
|
||||
|
||||
Note: The GitFlow naming convention for branches is as follows:
|
||||
|
||||
- Feature branches: feature/<feature-name>
|
||||
- Hotfix branches: hotfix/<hotfix-name>
|
||||
- Release branches: release/<major.minor.patch>(rc<number>)
|
||||
|
||||
## Build Release Workflow
|
||||
This GitHub Actions workflow is responsible for building and releasing software for multiple platforms (Windows, M1 MacOS, Intel MacOS, and Docker).
|
||||
The workflow has four jobs:
|
||||
|
||||
- `trigger-windows-build`
|
||||
- `trigger-macos-build`
|
||||
- `trigger-intel-build`
|
||||
- `trigger-docker-build`
|
||||
|
||||
Each job uses the `aurelien-baudet/workflow-dispatch` action to trigger another workflow, respectively `windows10_build.yml`, `m1_macos_build.yml`, `intel_macos_build.yml`, and `docker.yml`. The `GITHUB_TOKEN` is passed as a secret so that the triggered workflows have access to the necessary permissions. The `wait-for-completion-timeout` is set to 2 hours, which is the maximum amount of time the job will wait for the triggered workflow to complete.
|
||||
|
||||
## Docker Workflow
|
||||
This GitHub Actions workflow is responsible for building and pushing the docker image to the itHub Container Registry. This workflow is triggered when a new change is pushed to the main branch of the repository, and the Docker image is published to the GitHub Container Registry.
|
||||
|
||||
Steps
|
||||
-----
|
||||
|
||||
1. Checkout Code: This step checks out the code from the GitHub repository.
|
||||
|
||||
2. Login to GitHub Container Registry: This step logs into the GitHub Container Registry using the GitHub Actions token.
|
||||
|
||||
3. Setup Commit Hash: This step sets the commit hash of the code that is being built.
|
||||
|
||||
4. Build Env File: This step builds the environment file for the Docker image.
|
||||
|
||||
5. Building the Docker Image: This step builds the Docker image using the scripts in the `build/docker` directory.
|
||||
|
||||
6. Publishing the Docker Image: This step publishes the Docker image to the GitHub Container Registry. The Docker image is only pushed to the registry if the branch being built is `main`.
|
||||
|
||||
## Draft Workflow
|
||||
This GitHub Actions workflow is designed to automatically generate and update draft releases in a GitHub repository. The workflow is triggered when it is manually dispatched, allowing you to control when the draft releases are updated.
|
||||
|
||||
## GH Pages Workflow
|
||||
This GitHub Actions workflow is responsible for building the documentation and deploying it to GitHub Pages. This workflow is triggered when a new change is pushed to the `main` or `release` branch of the repository, and the documentation is published to GitHub Pages.
|
||||
|
||||
## Integration Test Workflow
|
||||
This GitHub Action is used to run integration tests on your code repository. It is triggered on pushes to the `release/*` or `main` branches, and it runs on the latest version of Ubuntu.
|
||||
|
||||
The workflow consists of the following steps:
|
||||
|
||||
1. Check out the code from the repository
|
||||
2. Set up Python 3.9
|
||||
3. Install Poetry, a package and dependency manager for Python
|
||||
4. Load a cached virtual environment created by Poetry, to speed up the process if possible
|
||||
5. Install dependencies specified in the `poetry.lock` file
|
||||
6. Run the integration tests using the `terminal.py` script
|
||||
7. Upload a summary of the test results to Slack
|
||||
|
||||
The results of the tests are captured in a file called `result.txt`. The summary of the tests, including information about failed tests, is then uploaded to Slack using the `adrey/slack-file-upload-action` GitHub Action.
|
||||
|
||||
## Intel MacOS Build Workflow
|
||||
This GitHub Actions workflow is responsible for building and testing the project on Intel Macs. The workflow is triggered by the workflow_dispatch event, which means it can be manually triggered. The concurrency group for the job is defined based on the Github workflow and the Github ref, and it is set to cancel in-progress runs.
|
||||
|
||||
The job named `Build` has several steps:
|
||||
|
||||
1. Checkout the repository's main branch.
|
||||
2. Git log to see the history of the repository.
|
||||
3. Install `create-dmg` using Homebrew.
|
||||
4. Clean up previous environment variables and set PATH to default.
|
||||
5. Set up conda environment caching.
|
||||
6. Set up Miniconda using the `build/conda/conda-3-9-env-full.yaml` file.
|
||||
7. Use Poetry to install the necessary dependencies.
|
||||
8. Install Pyinstaller.
|
||||
9. Install Portfolio Optimization and Forecasting Toolkits.
|
||||
10. Install a specific version of Papermill using pip.
|
||||
11. Build the bundle using Pyinstaller and do some additional tasks such as setting up icons.
|
||||
12. Create a keychain and decode a certificate using a password stored in Github secrets.
|
||||
13. Code sign specific binaries using the certificate and password from the previous step.
|
||||
|
||||
This workflow builds the OpenBB Terminal application on MacOS and signs it with a certificate to allow it to run on the MacOS system.
|
||||
|
||||
## Linting Workflow
|
||||
This GitHub Actions workflow is responsible for running linting checks on the codebase. This workflow is triggered on pull request events such as `opened`, `synchronize`, and `edited`, and push events on branches with names that start with `feature/`, `hotfix/`, or `release/`. The workflow also sets a number of environment variables and uses Github Actions caching to improve performance.
|
||||
|
||||
It consists of two jobs: `code-linting` and `markdown-link-check`.
|
||||
|
||||
The first job, `code-linting`, runs on an Ubuntu machine and performs several linting tasks on the code in the repository, including:
|
||||
|
||||
- Checking out the code from the repository
|
||||
- Setting up Python 3.9
|
||||
- Installing a number of Python packages necessary for the linting tasks
|
||||
- Running `bandit` to check for security vulnerabilities
|
||||
- Running `black` to check the code formatting
|
||||
- Running `codespell` to check the spelling of comments, strings, and variable names
|
||||
- Running `ruff` to check the use of Python
|
||||
- Running `mypy` to check the type annotations
|
||||
- Running `pyupgrade` to upgrade Python 2 code to Python 3
|
||||
- Running `pylint` to perform static analysis of the code
|
||||
|
||||
The second job, `markdown-link-check`, runs on an Ubuntu machine and performs linting of the markdown files in the repository. It uses a Docker container `avtodev/markdown-lint` to perform the linting.
|
||||
|
||||
## MacOS Build Workflow
|
||||
This GitHub Actions workflow is used to build a version of the OpenBB Terminal for M1 MacOS. The build process includes installing necessary dependencies, building the terminal application using PyInstaller, creating a DMG file for distribution, and running integration tests on the built application.
|
||||
|
||||
Jobs
|
||||
----
|
||||
|
||||
The workflow consists of a single job named `Build` which runs on self-hosted MacOS systems with ARM64 architecture. The job performs the following steps:
|
||||
|
||||
1. Checkout: The main branch of the repository is checked out, allowing for the commit hashes to line up.
|
||||
2. Git Log: The log of the Git repository is displayed.
|
||||
3. Install create-dmg: The `create-dmg` tool is installed using Homebrew.
|
||||
4. Clean Previous Path: The previous PATH environment variable is cleared and restored to its default values.
|
||||
5. Setup Conda Caching: The miniconda environment is set up using a caching mechanism for faster workflow execution after the first run.
|
||||
6. Setup Miniconda: Miniconda is set up using the `conda-3-9-env-full.yaml` environment file, with channels `conda-forge` and `defaults`, and with the `build_env` environment activated.
|
||||
7. Run Poetry: Poetry is used to install the dependencies for the project.
|
||||
8. Install PyInstaller: PyInstaller is installed using Poetry.
|
||||
9. Poetry Install Portfolio Optimization and Forecasting Toolkits: The portfolio optimization and forecasting toolkits are installed using Poetry.
|
||||
10. Install Specific Papermill: A specific version of Papermill is installed using pip.
|
||||
11. Build Bundle: The terminal application is built using PyInstaller, with icons and assets copied to the DMG directory.
|
||||
12. Create DMG: The DMG file is created using the `create-dmg` tool.
|
||||
13. Clean up Build Artifacts: The build artifacts such as the terminal directory and DMG directory are removed.
|
||||
14. Save Build Artifact DMG: The DMG file is saved as a build artifact.
|
||||
15. Convert & Mount DMG: The DMG file is converted and mounted.
|
||||
16. Directory Change: The current directory is changed to the mounted DMG file.
|
||||
17. Unmount DMG: The mounted DMG file is unmounted.
|
||||
18. Run Integration Tests: The built terminal application is run with integration tests, and the results are displayed.
|
||||
|
||||
Finally, the integration tests are run and the results are logged. The workflow is configured to run only when triggered by a workflow dispatch event and runs in a concurrent group, with the ability to cancel in-progress jobs.
|
||||
|
||||
## Nightly Build Workflow
|
||||
This code is a GitHub Actions workflow configuration file that is used to trigger other workflows when certain events occur. The main purpose of this workflow is to trigger builds on different platforms when a release is made or a pull request is made to the main branch.
|
||||
|
||||
This workflow is triggered at UTC+0 daily by the GitHub Action schedule event.
|
||||
|
||||
The job includes the following steps:
|
||||
|
||||
1. Trigger Windows Build: This step uses the `aurelien-baudet/workflow-dispatch` action to trigger the windows10_build.yml workflow.
|
||||
|
||||
2. Trigger macOS Build: This step uses the `aurelien-baudet/workflow-dispatch` action to trigger the m1_macos_build.yml workflow
|
||||
|
||||
3. Trigger Intel Build: This step uses the `aurelien-baudet/workflow-dispatch` action to trigger the intel_macos_build.yml workflow
|
||||
|
||||
4. Trigger Docker Build: This step uses the `aurelien-baudet/workflow-dispatch` action to trigger the docker.yml workflow
|
||||
|
||||
This workflow also uses a concurrency setting that groups the jobs by the workflow and ref, and cancels any in-progress jobs.
|
||||
|
||||
## pypi-publish Workflow
|
||||
The Github Action code `Deploy to PyPI` is used to deploy a Python project to PyPI (Python Package Index) and TestPyPI, which is a separate package index for testing purposes. The code is triggered on two events:
|
||||
|
||||
1. Push event: The code is triggered whenever there is a push to the `release/*` and `main` branches.
|
||||
|
||||
2. Workflow dispatch event: The code can be manually triggered by the workflow dispatch event.
|
||||
|
||||
The code sets the concurrency to the `group` and the option `cancel-in-progress` is set to `true` to ensure that the running jobs in the same `group` are cancelled in case another job is triggered.
|
||||
|
||||
The code contains two jobs, `deploy-test-pypi` and `deploy-pypi`, both of which have the same steps with slight variations.
|
||||
|
||||
The `deploy-test-pypi` job is triggered only if the pushed branch starts with `refs/heads/release/`. This job sets up the Python environment, installs the `build` package using `pip`, builds binary wheel and source tarball using `build`, and finally, publishes the distributions to TestPyPI using the `pypa/gh-action-pypi-publish@release/v1` Github Action. The `password` to access TestPyPI is stored as a secret named `TEST_PYPI_API_TOKEN`.
|
||||
|
||||
Similarly, the `deploy-pypi` job is triggered only if the pushed branch starts with `refs/heads/main`. This job follows the same steps as `deploy-test-pypi`, but the distributions are published to PyPI instead of TestPyPI. The `password` to access PyPI is stored as a secret named `PYPI_API_TOKEN`.
|
||||
|
||||
Note: The code uses the `pypa/build` package for building the binary wheel and source tarball, and the `pypa/gh-action-pypi-publish@release/v1` Github Action for publishing the distributions to PyPI and TestPyPI.
|
||||
|
||||
## Unit Tests Workflow
|
||||
This workflow is used to run unit tests on the OpenBB Terminal. The workflow is triggered on the following events:
|
||||
The events this workflow will respond to are:
|
||||
|
||||
1. Pull requests that are opened, synchronized, edited, or closed. The pull request must be made to the `develop` or `main` branches.
|
||||
|
||||
2. Pushes to the `release/*` branches.
|
||||
|
||||
Each job in the workflow specifies a set of steps that are executed in order.
|
||||
|
||||
The first job, `check-files-changed`, checks whether there are any changes to certain file types in the repository, such as Python files and lockfiles. If there are changes, then the `check-changes` output variable is set to `true`.
|
||||
|
||||
The next job, `base-test`, runs a series of tests if `check-changes` is `true` and the base branch of the pull request is `develop`. This job sets up a Python 3.9 environment, installs Poetry, and then runs tests using `pytest`. Finally, it starts the terminal and exits.
|
||||
|
||||
The next job, `tests-python`, runs tests for different versions of Python (3.8, 3.9, and 3.10) on the `ubuntu-latest` operating system. It sets up the specified Python version, installs Poetry and dependencies, and then runs tests using `pytest`.
|
||||
|
||||
The next job, `full-test`, uses the GitHub Actions `checkout` action to checkout the code, followed by the `setup-python` action to set up the specified version of Python. Then, the `install-poetry` action is used to install the package manager Poetry, and a cache is set up using the `actions/cache` action to avoid re-installing dependencies. After that, the dependencies are installed using Poetry, and a list of installed packages is displayed. Then, the tests are run using `pytest`, and finally, the `terminal.py` script is started and exited.
|
||||
|
||||
The last job, `tests-conda`, sets up a Miniconda environment using the `setup-miniconda` action. The environment is specified using a YAML file and is activated. Then, the tests are run.
|
||||
|
||||
## Windows 10 Build Workflow
|
||||
This is a GitHub Actions workflow file that automates the build and testing process for the OpenBB Terminal on Windows 10. The workflow consists of two jobs:
|
||||
|
||||
1. Windows-Build
|
||||
2. Build-Exe
|
||||
|
||||
- The Windows-Build job does the following:
|
||||
- Sets up the Windows Git configuration for long file paths.
|
||||
- Checks out the repository code.
|
||||
- Sets up Python 3.9 and creates an OpenBB environment using poetry.
|
||||
- Installs necessary packages and builds the terminal using PyInstaller.
|
||||
- Uploads the built artifact to GitHub as an artifact.
|
||||
- The Build-Exe job does the following:
|
||||
- Sets up the Windows Git configuration for long file paths.
|
||||
- Checks out the repository code.
|
||||
- Downloads the built artifact from the previous Windows-Build job.
|
||||
- Copies the files into an app folder for building the EXE file.
|
||||
- Builds the EXE file using NSIS.
|
||||
- Uploads the built EXE as an artifact to GitHub.
|
||||
- Runs integration tests on the terminal and saves the results to a text file.
|
||||
- Uploads the test results summary to Slack.
|
||||
- Cleans up previous build files and artifacts.
|
||||
|
||||
This workflow is triggered by the `workflow_dispatch` event and runs in concurrency with other workflows in the same group, with the ability to cancel in-progress builds. The concurrency group is defined as `${{ github.workflow }}-${{ github.ref }}`.
|
||||
3
.github/workflows/gh-pages.yml
vendored
3
.github/workflows/gh-pages.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
version: 1.3.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
@@ -76,4 +76,3 @@ jobs:
|
||||
# You can swap them out with your own user credentials.
|
||||
user_name: github-actions[bot]
|
||||
user_email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
|
||||
34
.github/workflows/integration-test.yml
vendored
34
.github/workflows/integration-test.yml
vendored
@@ -13,7 +13,17 @@ concurrency:
|
||||
jobs:
|
||||
integration-tests:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||
steps:
|
||||
- name: Slack Notification - Starting
|
||||
uses: act10ns/slack@v1
|
||||
with:
|
||||
status: starting
|
||||
channel: '#workflows'
|
||||
message: Starting Integration Test...
|
||||
if: always()
|
||||
|
||||
- name: Checkout code
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/checkout@v3
|
||||
@@ -31,7 +41,7 @@ jobs:
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
version: 1.3.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
@@ -47,6 +57,26 @@ jobs:
|
||||
run: poetry install --no-interaction -E optimization
|
||||
|
||||
- name: Run integration tests
|
||||
id: integration-tests
|
||||
run: |
|
||||
source $VENV
|
||||
python terminal.py /home/runner/work/OpenBBTerminal/OpenBBTerminal/openbb_terminal/miscellaneous/integration_tests_scripts -t
|
||||
python terminal.py -t > result.txt
|
||||
cat result.txt
|
||||
grep "================================ integration test summary ================================" result.txt -A100 | tail -c 2000 > failed_tests.txt
|
||||
|
||||
- name: Upload summary to Slack
|
||||
uses: adrey/slack-file-upload-action@master
|
||||
with:
|
||||
token: ${{ secrets.SLACK_API_TOKEN }}
|
||||
initial_comment: "Integration test summary"
|
||||
title: "Integration test summary"
|
||||
path: failed_tests.txt
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
|
||||
- name: Slack Notification - Success/Failure
|
||||
uses: act10ns/slack@v1
|
||||
with:
|
||||
status: ${{ job.status }}
|
||||
steps: ${{ toJson(steps) }}
|
||||
channel: '#workflows'
|
||||
if: always()
|
||||
|
||||
34
.github/workflows/intel_macos_build.yml
vendored
34
.github/workflows/intel_macos_build.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
steps:
|
||||
# Checkout repository main branch. this allows for the commit hashes to line up
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.2
|
||||
uses: actions/checkout@v3
|
||||
- name: Git Log
|
||||
run: git log
|
||||
# Install create-dmg
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
echo $PATH
|
||||
# Set up caching for conda env so that the workflow runs quickly after the first time
|
||||
- name: Setup Conda Caching
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/conda_pkgs_dir
|
||||
key: conda-macos-3-9-${{ hashFiles('build/conda/conda-3-9-env-full.yaml') }}
|
||||
@@ -53,19 +53,19 @@ jobs:
|
||||
activate-environment: build_env
|
||||
use-only-tar-bz2: true # Needed for caching some reason
|
||||
- name: Run Poetry
|
||||
run: poetry install
|
||||
- name: Install Pyinstaller
|
||||
run: poetry install -E installer
|
||||
- name: Install Portfolio Optimization and Forecasting Toolkits
|
||||
run: poetry install -E all
|
||||
run: |
|
||||
pip list
|
||||
python -m pip install -r requirements-full.txt
|
||||
- name: Install Specific Papermill
|
||||
run: |
|
||||
pip list
|
||||
pip uninstall papermill -y
|
||||
pip install git+https://github.com/nteract/papermill.git@main
|
||||
# This is basically the same as build4mac.sh
|
||||
- name: Build Bundle
|
||||
run: |
|
||||
pyinstaller build/pyinstaller/terminal.spec --clean
|
||||
pip list
|
||||
python -m PyInstaller build/pyinstaller/terminal.spec --clean
|
||||
osascript build/pyinstaller/setup_icons.applescript
|
||||
mkdir DMG
|
||||
cp -r build/pyinstaller/macOS_package_assets/* DMG/
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
rm -rf build/terminal
|
||||
rm -rf dist
|
||||
rm -rf DMG
|
||||
- name: Notorize DMG
|
||||
- name: Notarize DMG
|
||||
env:
|
||||
NOTARIZE_APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
|
||||
NOTARIZE_APPLE_PWD: ${{ secrets.NOTARIZE_APPLE_PWD }}
|
||||
@@ -177,8 +177,22 @@ jobs:
|
||||
cp -R OpenBB\ Terminal ~/Desktop
|
||||
- name: Unmount DMG
|
||||
run: hdiutil detach /dev/disk2
|
||||
|
||||
- name: Run Integration Tests
|
||||
run: /Users/openbb/Desktop/OpenBB\ Terminal/.OpenBB/OpenBBTerminal /Users/openbb/actions-runner/_work/OpenBBTerminal/OpenBBTerminal/openbb_terminal/miscellaneous/integration_tests_scripts -t
|
||||
run: |
|
||||
/Users/openbb/Desktop/OpenBB\ Terminal/.OpenBB/OpenBBTerminal -t -s forecast cryptocurrency reports alternative economy futures econometrics dashboards portfolio stocks/test_stocks_options_screen.openbb stocks/test_stocks_options.openbb forex etf stocks/test_stocks_fa.openbb > result.txt
|
||||
cat result.txt
|
||||
grep "================================ integration test summary ================================" result.txt -A100 | tail --bytes=2000 > failed_tests.txt
|
||||
|
||||
- name: Upload summary to Slack
|
||||
uses: adrey/slack-file-upload-action@master
|
||||
with:
|
||||
token: ${{ secrets.SLACK_API_TOKEN }}
|
||||
initial_comment: "Intel MacOs Build Integration test summary"
|
||||
title: "Intel MacOs Build Integration test summary"
|
||||
path: failed_tests.txt
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
|
||||
- name: Remove OpenBB Folder
|
||||
run: rm -rf /Users/openbb/Desktop/OpenBB\ Terminal
|
||||
- name: Remove OpenBB Exports Folder
|
||||
|
||||
2
.github/workflows/labels.yml
vendored
2
.github/workflows/labels.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
with:
|
||||
mode: minimum
|
||||
count: 1
|
||||
labels: "guides, bug, build, do not merge, docker, docs, duplicate, enhancement, feat XS, feat S, feat M, feat L, feat XL, help wanted, refactor, tests, discord, dependencies, notebookreports, dashboards, analytics, portfolio, installer, SDK, HACKTOBERFEST, "
|
||||
labels: "guides, bug, build, do not merge, docker, docs, duplicate, enhancement, feat XS, feat S, feat M, feat L, feat XL, help wanted, refactor, tests, discord, dependencies, notebookreports, dashboards, analytics, portfolio, installer, SDK, release "
|
||||
- uses: mheap/github-action-required-labels@v1
|
||||
with:
|
||||
mode: exactly
|
||||
|
||||
8
.github/workflows/linting.yml
vendored
8
.github/workflows/linting.yml
vendored
@@ -16,6 +16,8 @@ on:
|
||||
- 'feature/*'
|
||||
- 'hotfix/*'
|
||||
- 'release/*'
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
# Cancel previous runs that are not yet completed.
|
||||
concurrency:
|
||||
@@ -43,16 +45,14 @@ jobs:
|
||||
restore-keys: ${{ runner.os }}-linting-${{ hashFiles('**/poetry.lock') }}
|
||||
|
||||
- run: |
|
||||
pip install bandit black codespell mypy==0.982 pyupgrade safety pylint==2.15.2 packaging==22 ruff==0.0.236
|
||||
pip install bandit black codespell mypy==0.982 safety pylint==2.15.2 packaging==22 ruff==0.0.243
|
||||
pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
|
||||
- run: bandit -x ./tests -r . || true
|
||||
- run: black --diff --check .
|
||||
- run: codespell --ignore-words-list=commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot,te --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
|
||||
- run: ruff .
|
||||
- run: mypy --ignore-missing-imports openbb_terminal
|
||||
- run: shopt -s globstar && pyupgrade --py38-plus **/*.py
|
||||
- run: |
|
||||
pylint terminal.py openbb_terminal tests
|
||||
- run: pylint terminal.py openbb_terminal tests
|
||||
|
||||
markdown-link-check:
|
||||
name: Markdown Linting
|
||||
|
||||
121
.github/workflows/m1_macos_build.yml
vendored
121
.github/workflows/m1_macos_build.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
steps:
|
||||
# Checkout repository main branch. this allows for the commit hashes to line up
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.2
|
||||
uses: actions/checkout@v3
|
||||
- name: Git Log
|
||||
run: git log
|
||||
# Install create-dmg
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
echo $PATH
|
||||
# Set up caching for conda env so that the workflow runs quickly after the first time
|
||||
- name: Setup Conda Caching
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/conda_pkgs_dir
|
||||
key: conda-macos-3-9-${{ hashFiles('build/conda/conda-3-9-env-full.yaml') }}
|
||||
@@ -55,13 +55,9 @@ jobs:
|
||||
use-only-tar-bz2: true # Needed for caching some reason
|
||||
|
||||
- name: Run Poetry
|
||||
run: poetry install -vvv
|
||||
|
||||
- name: Install Pyinstaller
|
||||
run: poetry install -E installer
|
||||
|
||||
- name: Poetry Install Portfolio Optimization and Forecasting Toolkits
|
||||
run: poetry install -E all
|
||||
run: |
|
||||
pip list
|
||||
python -m pip install -r requirements-full.txt
|
||||
|
||||
- name: Install Specific Papermill
|
||||
run: |
|
||||
@@ -71,13 +67,102 @@ jobs:
|
||||
# This is basically the same as build4mac.sh
|
||||
- name: Build Bundle
|
||||
run: |
|
||||
pyinstaller build/pyinstaller/terminal.spec --clean
|
||||
python -m PyInstaller build/pyinstaller/terminal.spec --clean
|
||||
osascript build/pyinstaller/setup_icons.applescript
|
||||
mkdir DMG
|
||||
cp -r build/pyinstaller/macOS_package_assets/* DMG/
|
||||
mv dist/OpenBBTerminal DMG/OpenBB\ Terminal/.OpenBB
|
||||
- name: Creating Keychain
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
|
||||
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||
run: | # when pushing to main, make to generate new cert, and utilize secrets to store new password, and identity
|
||||
echo "Ensuring Keychain with same name does not exist"
|
||||
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
|
||||
echo "Decoding certificate"
|
||||
echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12
|
||||
echo "Creating Keychain"
|
||||
security create-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
|
||||
echo "Setting Default Keychain"
|
||||
security default-keychain -s build.keychain
|
||||
echo "Unlocking Keychain"
|
||||
security unlock-keychain -p $MACOS_KEYCHAIN_PWD build.keychain
|
||||
echo "Importing Keychain"
|
||||
security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign
|
||||
echo "Setting Partition List"
|
||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $MACOS_KEYCHAIN_PWD build.keychain
|
||||
- name: Codesign Specific Binaries
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
|
||||
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||
run: |
|
||||
echo "Code Signing SO Files"
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*.so
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*.so
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*.so
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*/*.so
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*/*/*.so
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*/*/*/*.so
|
||||
echo "Code Signing DYLIB Files"
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/*/*/*/*/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/.dylibs/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/cmdstan-2.26.1/stan/lib/stan_math/lib/tbb/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/torch/.dylibs/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/sklearn/.dylibs/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/scipy/.dylibs/*.dylib
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/xgboost/.dylibs/*.dylib
|
||||
|
||||
echo "Code Signing Other Files"
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/prophet_model.bin
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/cmdstan-2.26.1/bin/diagnose
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/cmdstan-2.26.1/bin/print
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/cmdstan-2.26.1/bin/stanc
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/prophet/stan_model/cmdstan-2.26.1/bin/stansummary
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/pyarrow/plasma-store-server
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/torch/bin/protoc
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/torch/bin/protoc-3.13.0.0
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/torch/bin/torch_shm_manager
|
||||
echo "Code Sign OpenBB Executable File"
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY DMG/OpenBB\ Terminal/.OpenBB/OpenBBTerminal
|
||||
- name: Create DMG
|
||||
run: create-dmg --volname "OpenBB Terminal" --volicon "images/dmg_volume.icns" --background "images/openbb_dmg_background.png" --icon "OpenBB Terminal" 190 250 --window-pos 190 120 --window-size 800 400 --icon-size 100 --text-size 14 --app-drop-link 600 250 --eula LICENSE --format UDZO --no-internet-enable "OpenBB Terminal".dmg DMG
|
||||
- name: Code Sign DMG Installer
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
|
||||
MACOS_KEYCHAIN_PWD: ${{ secrets.MACOS_KEYCHAIN_PWD }}
|
||||
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
|
||||
run: |
|
||||
echo "Code Signing DMG Installer"
|
||||
/usr/bin/codesign --deep --force --verify --verbose --options runtime --entitlements "build/pyinstaller/entitlements.plist" -s $MACOS_CODESIGN_IDENTITY OpenBB\ Terminal.dmg
|
||||
echo "Verify Signing"
|
||||
codesign --verify --deep --strict --verbose=2 OpenBB\ Terminal.dmg
|
||||
- name: Deleting Previous Keychain
|
||||
run: |
|
||||
echo "Deleting Previous Keychain to Clean Instance"
|
||||
rm -rf /Users/openbb/Library/Keychains/build.keychain-db
|
||||
- name: Clean up Build Artifacts
|
||||
run: |
|
||||
rm -rf build/terminal
|
||||
rm -rf dist
|
||||
rm -rf DMG
|
||||
- name: Notorize DMG
|
||||
env:
|
||||
NOTARIZE_APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
|
||||
NOTARIZE_APPLE_PWD: ${{ secrets.NOTARIZE_APPLE_PWD }}
|
||||
NOTARIZE_APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
|
||||
run: |
|
||||
xcrun notarytool submit OpenBB\ Terminal.dmg --apple-id "$NOTARIZE_APPLE_ID" --password "$NOTARIZE_APPLE_PWD" --team-id "$NOTARIZE_APPLE_TEAM_ID" --wait
|
||||
- name: Staple
|
||||
run: |
|
||||
xcrun stapler staple "OpenBB Terminal.dmg"
|
||||
- name: Clean up Build Artifacts
|
||||
run: |
|
||||
rm -rf build/terminal
|
||||
@@ -101,8 +186,22 @@ jobs:
|
||||
cp -R OpenBB\ Terminal ~/Desktop
|
||||
- name: Unmount DMG
|
||||
run: hdiutil detach /dev/disk4
|
||||
|
||||
- name: Run Integration Tests
|
||||
run: /Users/openbb/Desktop/OpenBB\ Terminal/.OpenBB/OpenBBTerminal /Users/openbb/actions-runner/_work/OpenBBTerminal/OpenBBTerminal/openbb_terminal/miscellaneous/integration_tests_scripts -t
|
||||
run: |
|
||||
/Users/openbb/Desktop/OpenBB\ Terminal/.OpenBB/OpenBBTerminal -t -s forecast cryptocurrency reports alternative economy futures econometrics dashboards portfolio stocks/test_stocks_options_screen.openbb stocks/test_stocks_options.openbb forex etf stocks/test_stocks_fa.openbb > result.txt
|
||||
cat result.txt
|
||||
grep "================================ integration test summary ================================" result.txt -A100 | tail --bytes=2000 > failed_tests.txt
|
||||
|
||||
- name: Upload summary to Slack
|
||||
uses: adrey/slack-file-upload-action@master
|
||||
with:
|
||||
token: ${{ secrets.SLACK_API_TOKEN }}
|
||||
initial_comment: "M1 MacOs Build Integration test summary"
|
||||
title: "M1 MacOs Build Integration test summary"
|
||||
path: failed_tests.txt
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
|
||||
- name: Remove OpenBB Folder
|
||||
run: rm -rf /Users/openbb/Desktop/OpenBB\ Terminal
|
||||
- name: Remove OpenBB Exports Folder
|
||||
|
||||
10
.github/workflows/nightly-build.yml
vendored
10
.github/workflows/nightly-build.yml
vendored
@@ -13,7 +13,7 @@ on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
permissions:
|
||||
permissions:
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
@@ -25,8 +25,8 @@ jobs:
|
||||
with:
|
||||
workflow: windows10_build.yml
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-for-completion-timeout: 2h
|
||||
|
||||
wait-for-completion-timeout: 3h
|
||||
|
||||
trigger-macos-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
workflow: m1_macos_build.yml
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-for-completion-timeout: 2h
|
||||
|
||||
|
||||
trigger-intel-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
workflow: intel_macos_build.yml
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-for-completion-timeout: 2h
|
||||
|
||||
|
||||
trigger-docker-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
79
.github/workflows/pypi.yml
vendored
Normal file
79
.github/workflows/pypi.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
name: Deploy to PyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- release/*
|
||||
- main
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy-test-pypi:
|
||||
name: Build and publish distributions 📦 to PyPI and TestPyPI
|
||||
if: startsWith(github.ref, 'refs/heads/release/')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.9"
|
||||
|
||||
- name: Install pypa/build
|
||||
run: >-
|
||||
python -m
|
||||
pip install
|
||||
build
|
||||
--user
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: >-
|
||||
python -m
|
||||
build
|
||||
--sdist
|
||||
--wheel
|
||||
--outdir dist/
|
||||
.
|
||||
|
||||
- name: Publish distribution 📦 to Test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
repository_url: https://test.pypi.org/legacy/
|
||||
|
||||
deploy-pypi:
|
||||
name: Build and publish distributions 📦 to PyPI and TestPyPI
|
||||
if: startsWith(github.ref, 'refs/heads/main')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.9"
|
||||
|
||||
- name: Install pypa/build
|
||||
run: >-
|
||||
python -m
|
||||
pip install
|
||||
build
|
||||
--user
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: >-
|
||||
python -m
|
||||
build
|
||||
--sdist
|
||||
--wheel
|
||||
--outdir dist/
|
||||
.
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
259
.github/workflows/test.yml
vendored
259
.github/workflows/test.yml
vendored
@@ -1,259 +0,0 @@
|
||||
name: Tests
|
||||
env:
|
||||
OPENBB_ENABLE_QUICK_EXIT: true
|
||||
OPENBB_LOG_COLLECT: false
|
||||
OPENBB_USE_ION: false
|
||||
OPENBB_USE_PROMPT_TOOLKIT: false
|
||||
OPENBB_FILE_OVERWRITE: true
|
||||
PIP_DEFAULT_TIMEOUT: 100
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
linting:
|
||||
name: General Linting
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # actions/checkout v3.0.2
|
||||
|
||||
- name: Setup Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.9"
|
||||
architecture: x64
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-linting-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: ${{ runner.os }}-linting-${{ hashFiles('**/poetry.lock') }}
|
||||
|
||||
- run: pip install bandit black codespell mypy==0.982 pyupgrade safety pylint==2.15.2 packaging==22 ruff==0.0.212
|
||||
- run: pip install types-pytz types-requests types-termcolor types-tabulate types-PyYAML types-python-dateutil types-setuptools types-six
|
||||
- run: bandit -x ./tests -r . || true
|
||||
- run: black --diff --check .
|
||||
- run: codespell --ignore-words-list=commun,statics,ro,zar,zlot,jewl,ba,buil,coo,ether,hist,hsi,mape,navagation,operatio,pres,ser,yeld,shold,ist,varian,datas,ake,creat,vie,hel,ket,toke,certi,buidl,ot,te --quiet-level=2 --skip=./tests,.git,*.css,*.csv,*.html,*.ini,*.ipynb,*.js,*.json,*.lock,*.scss,*.txt,*.yaml,./build/pyinstaller,./website/config.toml
|
||||
- run: ruff .
|
||||
- run: mypy --ignore-missing-imports openbb_terminal
|
||||
- run: shopt -s globstar && pyupgrade --py38-plus **/*.py
|
||||
- run: safety check
|
||||
- run: |
|
||||
pylint terminal.py openbb_terminal tests
|
||||
test:
|
||||
name: Base Tests - Ubuntu-latest - Python 3.9
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Python 3.9
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.9"
|
||||
architecture: x64
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-${{ runner.os }}-v1-${{ hashFiles('**/poetry.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
run: poetry install --no-interaction -E optimization
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
MPLBACKEND: Agg
|
||||
run: |
|
||||
source $VENV
|
||||
pytest tests/ --optimization
|
||||
|
||||
- name: Start Terminal and exit
|
||||
run: |
|
||||
source $VENV
|
||||
python terminal.py
|
||||
markdown-link-check:
|
||||
name: Markdown Linting
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
name: Check out the code
|
||||
- name: Lint Code Base
|
||||
uses: docker://avtodev/markdown-lint:v1
|
||||
with:
|
||||
args: "./*.md ./changelogs/*.md ./openbb_terminal/**/*.md ./discordbot/**/*.md"
|
||||
tests-python:
|
||||
name: Vanilla Python Tests - (${{ matrix.python-version }}, ${{ matrix.os }})
|
||||
needs: test
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
exclude:
|
||||
- os: ubuntu-latest
|
||||
python-version: "3.9"
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: x64
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-${{ runner.os }}-v1-${{ hashFiles('**/poetry.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
run: poetry install --no-interaction -E optimization
|
||||
|
||||
- name: List installed packages
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
source $VENV
|
||||
pip list
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
MPLBACKEND: Agg
|
||||
run: |
|
||||
source $VENV
|
||||
pytest tests/ --optimization
|
||||
|
||||
- name: Start Terminal and exit
|
||||
run: |
|
||||
source $VENV
|
||||
python terminal.py
|
||||
tests-conda:
|
||||
name: Anaconda Python Tests - (${{ matrix.python-version }}, ${{ matrix.os }})
|
||||
needs: test
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu", "windows"]
|
||||
python-version: ["3.9"]
|
||||
dependencies: [""]
|
||||
include:
|
||||
- os: ubuntu
|
||||
python: 3.9
|
||||
- os: windows
|
||||
python: 3.9
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
PYTHON: ${{ matrix.python }}
|
||||
PYTHONNOUSERSITE: 1
|
||||
steps:
|
||||
- name: Set git to use LF
|
||||
if: runner.os == 'Windows'
|
||||
run: |
|
||||
git config --global core.autocrlf false
|
||||
git config --global core.eol lf
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
# Need to fetch more than the last commit so that setuptools-scm can
|
||||
# create the correct version string. If the number of commits since
|
||||
# the last release is greater than this, the version still be wrong.
|
||||
# Increase if necessary.
|
||||
fetch-depth: 100
|
||||
# The GitHub token is preserved by default but this job doesn't need
|
||||
# to be able to push to GitHub.
|
||||
persist-credentials: false
|
||||
|
||||
- name: Setup caching for conda packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/conda_pkgs_dir
|
||||
key: conda-${{ runner.os }}-v1-${{ matrix.python }}-${{ hashFiles('build/conda/conda-3-9-env-full.yaml') }}
|
||||
|
||||
- name: Setup Miniconda
|
||||
uses: conda-incubator/setup-miniconda@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
miniconda-version: "latest"
|
||||
auto-update-conda: true
|
||||
channels: conda-forge,defaults
|
||||
show-channel-urls: true
|
||||
channel-priority: flexible
|
||||
environment-file: build/conda/conda-3-9-env.yaml
|
||||
activate-environment: testing
|
||||
# Needed for caching
|
||||
use-only-tar-bz2: true
|
||||
|
||||
- name: Update Temp permissions on windows
|
||||
if: runner.os == 'Windows'
|
||||
shell: cmd /C CALL {0}
|
||||
run: >-
|
||||
c:\windows\system32\icacls C:\Users\runneradmin\AppData\Local\Temp /grant "everyone":F /t
|
||||
|
||||
- name: Get pip cache dir
|
||||
shell: bash -l {0}
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: pip cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-v1-3-9-pip-${{ hashFiles('requirements-full.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-v1-pip-
|
||||
|
||||
- name: Uninstall Brotlipy
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda remove brotlipy -y
|
||||
|
||||
- name: Install dependencies (Bash)
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
pip install --requirement requirements-full.txt
|
||||
|
||||
- name: List installed packages (Bash)
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda list
|
||||
pip list
|
||||
|
||||
- name: Run tests (Bash)
|
||||
env:
|
||||
MPLBACKEND: Agg
|
||||
shell: bash -l {0}
|
||||
run: pytest tests/ -m "not linux" --optimization
|
||||
|
||||
- name: Start Terminal and exit
|
||||
shell: bash -l {0}
|
||||
run: python terminal.py
|
||||
35
.github/workflows/unit-test.yml
vendored
35
.github/workflows/unit-test.yml
vendored
@@ -6,6 +6,8 @@ env:
|
||||
OPENBB_USE_ION: false
|
||||
OPENBB_USE_PROMPT_TOOLKIT: false
|
||||
OPENBB_FILE_OVERWRITE: true
|
||||
OPENBB_ENABLE_CHECK_API: false
|
||||
OPENBB_PREVIOUS_USER: true
|
||||
PIP_DEFAULT_TIMEOUT: 100
|
||||
|
||||
on:
|
||||
@@ -17,7 +19,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- release/*
|
||||
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
@@ -32,7 +35,7 @@ jobs:
|
||||
check-changes: ${{ steps.check-changes.outputs.check-changes }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 100
|
||||
# The GitHub token is preserved by default but this job doesn't need
|
||||
@@ -76,7 +79,7 @@ jobs:
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
version: 1.3.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
@@ -128,7 +131,7 @@ jobs:
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
version: 1.3.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
@@ -167,7 +170,7 @@ jobs:
|
||||
# Run only when a PR is merged or a push to release/* branch
|
||||
if: github.event_name == 'push' || github.event.pull_request.merged == true
|
||||
strategy:
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.8", "3.9", "3.10"]
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
@@ -187,7 +190,7 @@ jobs:
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.1.13
|
||||
version: 1.3.2
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
@@ -200,7 +203,8 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
run: poetry install --no-interaction -E optimization
|
||||
run: |
|
||||
poetry install --no-interaction -E optimization
|
||||
|
||||
- name: List installed packages
|
||||
shell: bash -l {0}
|
||||
@@ -208,6 +212,11 @@ jobs:
|
||||
source $VENV
|
||||
pip list
|
||||
|
||||
- name: Start Terminal and exit
|
||||
run: |
|
||||
source $VENV
|
||||
python terminal.py
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
MPLBACKEND: Agg
|
||||
@@ -215,11 +224,6 @@ jobs:
|
||||
source $VENV
|
||||
pytest tests/ --optimization --autodoc
|
||||
|
||||
- name: Start Terminal and exit
|
||||
run: |
|
||||
source $VENV
|
||||
python terminal.py
|
||||
|
||||
tests-conda:
|
||||
name: Anaconda Python Tests - (${{ matrix.python-version }}, ${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
@@ -227,7 +231,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu", "windows"]
|
||||
os: ["ubuntu", "windows", "macos"]
|
||||
python-version: ["3.9"]
|
||||
dependencies: [""]
|
||||
include:
|
||||
@@ -299,11 +303,6 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-v1-pip-
|
||||
|
||||
- name: Uninstall Brotlipy
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
conda remove brotlipy -y
|
||||
|
||||
- name: Install dependencies (Bash)
|
||||
shell: bash -l {0}
|
||||
run: |
|
||||
|
||||
28
.github/workflows/windows10_build.yml
vendored
28
.github/workflows/windows10_build.yml
vendored
@@ -17,7 +17,7 @@ concurrency:
|
||||
jobs:
|
||||
Windows-Build:
|
||||
name: Windows10 Build ENV
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
# Configuring -------------
|
||||
steps:
|
||||
- name: Setup Windows Git Configuration # This is under the assumption that git is already installed on the system
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
git config --system core.longpaths true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python & Create OpenBB Environment
|
||||
uses: actions/setup-python@v4
|
||||
@@ -38,10 +38,9 @@ jobs:
|
||||
python -m venv venv
|
||||
source venv/Scripts/activate
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install poetry==1.1.13
|
||||
python -m pip install setuptools==64.0.2 wheel
|
||||
python -m pip install charset_normalizer==2.1.1
|
||||
python -m poetry install -E installer -E all
|
||||
python -m pip install -r requirements-full.txt
|
||||
python -m pip uninstall papermill -y
|
||||
python -m pip install git+https://github.com/nteract/papermill.git@main
|
||||
python -m PyInstaller build/pyinstaller/terminal.spec --clean
|
||||
@@ -67,7 +66,7 @@ jobs:
|
||||
git config --system core.longpaths true
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2.4.2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download Artifact
|
||||
uses: actions/download-artifact@v2
|
||||
@@ -84,6 +83,12 @@ jobs:
|
||||
run: |
|
||||
C:\'.\Program Files (x86)\'\nsis\makensis.exe .\build\nsis\setup.nsi
|
||||
|
||||
# This should autosign the installer now - We really need to only do this when needed though. ON RELEASE
|
||||
- name: Sign Installer
|
||||
if: startsWith(github.ref, 'refs/heads/main')
|
||||
run: |
|
||||
& 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86\signtool.exe' sign /fd sha256 /tr http://ts.ssl.com /td sha256 /sha1 26a8e28dbe3b1db7407b92d7de97c290d4436a32 'C:\Users\Administrator\actions-runner\_work\OpenBBTerminal\OpenBBTerminal\build\nsis\OpenBB Terminal Setup.exe'
|
||||
|
||||
- name: Save Build Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -92,7 +97,18 @@ jobs:
|
||||
|
||||
- name: Run Integration Tests
|
||||
run: |
|
||||
dist\OpenBBTerminal\OpenBBTerminal.exe -t
|
||||
dist\OpenBBTerminal\OpenBBTerminal.exe -t -s forecast cryptocurrency reports alternative economy futures econometrics dashboards portfolio stocks/test_stocks_options_screen.openbb stocks/test_stocks_options.openbb forex etf stocks/test_stocks_fa.openbb > result.txt
|
||||
cat result.txt
|
||||
Select-String "================================ integration test summary ================================" result.txt -Context 0,100 | Select-Object -Last 2000 | Out-File failed_tests.txt
|
||||
|
||||
- name: Upload summary to Slack
|
||||
uses: adrey/slack-file-upload-action@master
|
||||
with:
|
||||
token: ${{ secrets.SLACK_API_TOKEN }}
|
||||
initial_comment: "Windows Build Integration test summary"
|
||||
title: "Windows Build Integration test summary"
|
||||
path: failed_tests.txt
|
||||
channel: ${{ secrets.SLACK_CHANNEL_ID }}
|
||||
|
||||
# Cleaning ------------------------
|
||||
# Make sure to add Remove-Item C:\Users\Administrator\Desktop\OPENBB-exports -Recurse whenever integration tests get fixed
|
||||
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -39,6 +39,7 @@ website/functions
|
||||
*_sdk_audit.csv
|
||||
website/terminaltest
|
||||
!build/docker/compose.env
|
||||
.dccache
|
||||
|
||||
# pyinstaller artifacts
|
||||
*.pyo
|
||||
@@ -48,19 +49,6 @@ build/nsis/app
|
||||
DMG/*
|
||||
*.dmg
|
||||
|
||||
# Jupyter Lab Extension build files
|
||||
jupyterlab/**/build
|
||||
jupyterlab/*/*.bundle.*
|
||||
jupyterlab/*/lib/
|
||||
jupyterlab/*/*/labextension/
|
||||
jupyterlab/*/node_modules/
|
||||
jupyterlab/*/*/node_modules/
|
||||
jupyterlab/*/*.egg-info/
|
||||
jupyterlab/*/.ipynb_checkpoints
|
||||
jupyterlab/*/*.tsbuildinfo
|
||||
jupyterlab/*/ui-tests/test-results/
|
||||
jupyterlab/*/ui-tests/tests/*.ts-snapshots/
|
||||
|
||||
# User stylesheets
|
||||
styles/user
|
||||
|
||||
@@ -73,3 +61,6 @@ darts_logs/
|
||||
# User data
|
||||
custom_imports/*.csv
|
||||
custom_imports/*/*.csv
|
||||
|
||||
# lightning logs
|
||||
lightning_logs/
|
||||
|
||||
7
.pre-commit-config.yaml
vendored
7
.pre-commit-config.yaml
vendored
@@ -14,7 +14,7 @@ repos:
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: 'v0.0.236'
|
||||
rev: 'v0.0.243'
|
||||
hooks:
|
||||
- id: ruff
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
@@ -64,11 +64,6 @@ repos:
|
||||
"website/content/api/*",
|
||||
]
|
||||
exclude: package.lock.json
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py38-plus]
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: reserved_args
|
||||
|
||||
215
CONTRIBUTING.md
vendored
215
CONTRIBUTING.md
vendored
@@ -13,7 +13,6 @@ Use your best judgment, and feel free to propose changes to this document in a p
|
||||
- [View](#view)
|
||||
- [Controller](#controller)
|
||||
- [Add SDK endpoint](#add-sdk-endpoint)
|
||||
- [Add Documentation](#add-documentation)
|
||||
- [Open a Pull Request](#open-a-pull-request)
|
||||
- [Review Process](#review-process)
|
||||
- [Understand Code Structure](#understand-code-structure)
|
||||
@@ -310,160 +309,40 @@ In addition, note the `self.load_class` which allows to not create a new DarkPoo
|
||||
|
||||
In order to add a command to the SDK, follow these steps:
|
||||
|
||||
1. Go to the `sdk.py` file and scroll to the `functions` dictionary, it should look like this:
|
||||
1. Go to the `trail_map.csv` file located in `openbb_terminal/miscellaneous/library`, which should look like this:
|
||||
|
||||
```python
|
||||
functions = {
|
||||
"stocks.get_news": {
|
||||
"model": "openbb_terminal.common.newsapi_model.get_news",
|
||||
},
|
||||
"stocks.load": {
|
||||
"model": "openbb_terminal.stocks.stocks_helper.load",
|
||||
},
|
||||
"stocks.candle": {
|
||||
"model": "openbb_terminal.stocks.stocks_helper.load",
|
||||
"view": "openbb_terminal.stocks.stocks_helper.display_candle",
|
||||
},
|
||||
```csv
|
||||
trail,model,view
|
||||
|
||||
...
|
||||
stocks.fa.rot,openbb_terminal.stocks.fundamental_analysis.finnhub_model.get_rating_over_time,openbb_terminal.stocks.fundamental_analysis.finnhub_view.rating_over_time
|
||||
stocks.fa.analyst,openbb_terminal.stocks.fundamental_analysis.finviz_model.get_analyst_data,
|
||||
```
|
||||
|
||||
2. Add a new key to the dictionary, which corresponds to the way the added command shall be accessed from the sdk.
|
||||
This is called the `virtual path`. In this case it should be `stocks.dps.shorted`.
|
||||
3. Now it is time to add the value to the key. This key shall be another dictionary with a `model` key and possibly a
|
||||
`view` key.
|
||||
1. The model keys value should be the path from project root to the new commands model function as a string. This
|
||||
case it is `openbb_terminal.stocks.dark_pool_shorts.yahoofinance_model.get_most_shorted`.
|
||||
2. If and **only if** the view function of the command **displays a chart**, then the `view` key and its value is
|
||||
the view functions path from the project root as a string. In this example the view function of the only prints a
|
||||
table and thus this step can be ignored.
|
||||
4. Done!!! The final new dictionary looks like this after the added example:
|
||||
In this file, the trail represents the path to the function to be called. The model represents the path to the model function and the view represents the path to the view function. Note that the second line does not have an associated view function, so we leave that column empty (the trailing comma is required to load).
|
||||
|
||||
```python
|
||||
functions = {
|
||||
...
|
||||
2. Add your new function to this structure. In our example of the `shorted` function, our trail would be `stocks.dps.shorted`.
|
||||
The model is the path to the `_model` function that was written, `openbb_terminal.stocks.dark_pool_shorts.yahoofinance_model.get_most_shorted`.
|
||||
The view is the path to the `_view` function that was written: `openbb_terminal.stocks.dark_pool_shorts.yahoofinance_view.display_most_shorted`.
|
||||
The added line of the file should look like this:
|
||||
|
||||
"stocks.dps.shorted": {
|
||||
"model": "openbb_terminal.stocks.dark_pool_shorts.yahoofinance_model.get_most_shorted",
|
||||
},
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### Add Documentation
|
||||
|
||||
To check whether documentation is added correctly follow [Hugo Server instructions](/website/README.md).
|
||||
|
||||
This is the structure that the documentation follows:
|
||||
|
||||
```txt
|
||||
website/content/_index.md
|
||||
/stocks/_index.md
|
||||
/load/_index.md
|
||||
/candle/_index.md
|
||||
/discovery/_index.md
|
||||
/ipo/_index.md
|
||||
/...
|
||||
/...
|
||||
/...
|
||||
/cryptocurrency/_index.md
|
||||
/chart/_index.md
|
||||
/defi/_index.md
|
||||
/borrow/_index.md
|
||||
/...
|
||||
/...
|
||||
/...
|
||||
/common/_index.md
|
||||
/technical_analysis/_index.md
|
||||
/ema/_index.md
|
||||
/...
|
||||
/...
|
||||
```
|
||||
|
||||
Note that the `common` folder holds features that are common across contexts, e.g. `technical analysis` can be performed on both `stocks` or `crytpo`.
|
||||
|
||||
To add a new command, there are two main actions that need to be done:
|
||||
|
||||
1. Create a directory with the name of the command and a `_index.md` file within. Examples:
|
||||
|
||||
- When adding `ipo`, since this command belongs to context `stocks` and category `discovery`, we added a `ipo` folder with a `_index.md` file within to `website/content/stocks/discovery`.
|
||||
|
||||
- When adding `candle`, since this command belongs to context `stocks`, we added a `candle` folder with a `_index.md` file within to `website/content/stocks/`.
|
||||
|
||||
2. The `_index.md` file should have the output of the `command -h` followed by a screenshot example of what the user can expect. Note that you can now drag and drop the images while editing the readme file on the remote web version of your PR branch. Github will create a link for it with format (<https://user-images.githubusercontent.com/***/***.file_format>).
|
||||
|
||||
Example:
|
||||
|
||||
---
|
||||
|
||||
```shell
|
||||
usage: ipo [--past PAST_DAYS] [--future FUTURE_DAYS]
|
||||
```
|
||||
|
||||
Past and future IPOs. [Source: <https://finnhub.io>]
|
||||
|
||||
- --past : Number of past days to look for IPOs. Default 0.
|
||||
- --future : Number of future days to look for IPOs. Default 10.
|
||||
|
||||
<IMAGE HERE - Use drag and drop hint mentioned above>
|
||||
|
||||
---
|
||||
|
||||
3. Update the Navigation bar to match the content you've added. This is done by adding 2 lines of code to `website/data/menu/`, i.e. a `name` and a `ref`. Example:
|
||||
|
||||
```python
|
||||
---
|
||||
main:
|
||||
- name: stocks
|
||||
ref: "/stocks"
|
||||
sub:
|
||||
- name: load
|
||||
ref: "/stocks/load"
|
||||
- name: candle
|
||||
ref: "/stocks/candle"
|
||||
- name: discovery
|
||||
ref: "/stocks/discovery"
|
||||
sub:
|
||||
- name: ipo
|
||||
ref: "/stocks/discovery/ipo"
|
||||
- name: map
|
||||
ref: "/stocks/discovery/map"
|
||||
```csv
|
||||
stocks.dps.shorted,openbb_terminal.stocks.dark_pool_shorts.yahoofinance_model.get_most_shorted,openbb_terminal.stocks.dark_pool_shorts.yahoofinance_view.display_most_shorted
|
||||
```
|
||||
|
||||
### Open a Pull Request
|
||||
|
||||
Once you're happy with what you have, push your branch to remote. E.g. `git push origin feature/AmazingFeature`
|
||||
Once you're happy with what you have, push your branch to remote. E.g. `git push origin feature/AmazingFeature`. Note that we follow gitflow naming convention, so your branch name should be prefixed with `feature/` or `hotfix/` depending on the type of work you are doing.
|
||||
|
||||
A user may create a **Draft Pull Request** when he/she wants to discuss implementation with the team.
|
||||
|
||||
The team will then assign your PR one of the following labels:
|
||||
|
||||
| Label name | Description | Example |
|
||||
| -------------- | ----------------------------------- | ---------------------------------------------- |
|
||||
| `feat XS` | Extra small feature | Add a preset |
|
||||
| `feat S` | Small T-Shirt size Feature | New single command added |
|
||||
| `feat M` | Medium T-Shirt size feature | Multiple commands added from same data source |
|
||||
| `feat L` | Large T-Shirt size Feature | New category added under context |
|
||||
| `feat XL` | Extra Large feature | New context added |
|
||||
| `enhancement` | Enhancement | Add new parameter to existing command |
|
||||
| `bug` | Fix a bug | Fixes terminal crashing or warning message |
|
||||
| `build` | Build-related work | Fix a github action that is breaking the build |
|
||||
| `tests` | Test-related work | Add/improve tests |
|
||||
| `docs` | Improvements on documentation | Add/improve documentation |
|
||||
| `refactor` | Refactor code | Changing argparse location |
|
||||
| `docker` | Docker-related work | Add/improve docker |
|
||||
| `help wanted` | Extra attention is needed | When a contributor needs help |
|
||||
| `do not merge` | Label to prevent pull request merge | When PR is not ready to be merged just yet |
|
||||
|
||||
### Review Process
|
||||
|
||||
As soon as the Pull Request is opened, our repository has a specific set of github actions that will not only run
|
||||
linters on the branch just pushed, but also run pytest on it. This allows for another layer of safety on the code developed.
|
||||
|
||||
In addition, our team is known for performing `diligent` code reviews. This not only allows us to reduce the amount of
|
||||
iterations on that code and have it to be more future proof, but also allows the developer to learn/improve his coding skills.
|
||||
In addition, our team is known for performing `diligent` code reviews. This not only allows us to reduce the amount of iterations on that code and have it to be more future proof, but also allows the developer to learn/improve his coding skills.
|
||||
|
||||
Often in the past the reviewers have suggested better coding practices, e.g. using `1_000_000` instead of `1000000` for
|
||||
better visibility, or suggesting a speed optimization improvement.
|
||||
Often in the past the reviewers have suggested better coding practices, e.g. using `1_000_000` instead of `1000000` forbetter visibility, or suggesting a speed optimization improvement.
|
||||
|
||||
## Understand Code Structure
|
||||
|
||||
@@ -1100,9 +979,8 @@ The following linters are used by our codebase:
|
||||
| bandit | security analyzer |
|
||||
| black | code formatter |
|
||||
| codespell | spelling checker |
|
||||
| flake8 | style guide enforcer |
|
||||
| ruff | a fast python linter |
|
||||
| mypy | static typing checker |
|
||||
| pyupgrade | upgrade syntax for newer versions |
|
||||
| safety | checks security vulnerabilities |
|
||||
| pylint | bug and quality checker |
|
||||
| markdownlint | markdown linter |
|
||||
@@ -1146,39 +1024,46 @@ Note that a `OPENBB_` is added so that the user knows that that environment vari
|
||||
|
||||
One of the first steps once adding a new data source that requires an API key is to add that key to our [keys_controller.py](/openbb_terminal/keys_controller.py). This menu allows the user to set API keys and check their validity.
|
||||
|
||||
The following code allows to check the validity of the IEX Cloud API key.
|
||||
The following code allows to check the validity of the Polygon API key.
|
||||
|
||||
```python
|
||||
def check_iex_key(show_output: bool = False) -> str:
|
||||
"""Check IEX Cloud key
|
||||
|
||||
def check_polygon_key(show_output: bool = False) -> str:
|
||||
"""Check Polygon key
|
||||
|
||||
Parameters
|
||||
----------
|
||||
show_output: bool
|
||||
Display status string or not.
|
||||
show_output: bool
|
||||
Display status string or not. By default, False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
status: str
|
||||
|
||||
str
|
||||
Status of key set
|
||||
"""
|
||||
|
||||
if cfg.API_IEX_TOKEN == "REPLACE_ME": # nosec
|
||||
logger.info("IEX Cloud key not defined")
|
||||
if cfg.API_POLYGON_KEY == "REPLACE_ME":
|
||||
logger.info("Polygon key not defined")
|
||||
status = KeyStatus.NOT_DEFINED
|
||||
else:
|
||||
try:
|
||||
pyEX.Client(api_token=cfg.API_IEX_TOKEN, version="v1").quote(symbol="AAPL")
|
||||
logger.info("IEX Cloud key defined, test passed")
|
||||
status = KeyStatus.DEFINED_TEST_PASSED
|
||||
except Exception as _: # noqa: F841
|
||||
logger.warning("IEX Cloud key defined, test failed")
|
||||
r = request(
|
||||
"https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/2020-06-01/2020-06-17"
|
||||
f"?apiKey={cfg.API_POLYGON_KEY}"
|
||||
)
|
||||
if r.status_code in [403, 401]:
|
||||
logger.warning("Polygon key defined, test failed")
|
||||
status = KeyStatus.DEFINED_TEST_FAILED
|
||||
elif r.status_code == 200:
|
||||
logger.info("Polygon key defined, test passed")
|
||||
status = KeyStatus.DEFINED_TEST_PASSED
|
||||
else:
|
||||
logger.warning("Polygon key defined, test inconclusive")
|
||||
status = KeyStatus.DEFINED_TEST_INCONCLUSIVE
|
||||
|
||||
if show_output:
|
||||
console.print(status.colorize() + "\n")
|
||||
console.print(status.colorize())
|
||||
|
||||
return status
|
||||
return str(status)
|
||||
```
|
||||
|
||||
Note that there are usually 3 states:
|
||||
@@ -1193,13 +1078,13 @@ A function can then be created with the following format to allow the user to ch
|
||||
|
||||
```python
|
||||
@log_start_end(log=logger)
|
||||
def call_iex(self, other_args: List[str]):
|
||||
"""Process iex command"""
|
||||
def call_polygon(self, other_args: List[str]):
|
||||
"""Process polygon command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="iex",
|
||||
description="Set IEX Cloud API key.",
|
||||
prog="polygon",
|
||||
description="Set Polygon API key.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-k",
|
||||
@@ -1209,13 +1094,14 @@ def call_iex(self, other_args: List[str]):
|
||||
help="key",
|
||||
)
|
||||
if not other_args:
|
||||
console.print("For your API Key, visit: https://iexcloud.io\n")
|
||||
console.print("For your API Key, visit: https://polygon.io\n")
|
||||
return
|
||||
|
||||
if other_args and "-" not in other_args[0][0]:
|
||||
other_args.insert(0, "-k")
|
||||
ns_parser = parse_simple_args(parser, other_args)
|
||||
ns_parser = self.parse_simple_args(parser, other_args)
|
||||
if ns_parser:
|
||||
self.status_dict["iex"] = keys_model.set_iex_key(
|
||||
self.status_dict["polygon"] = keys_model.set_polygon_key(
|
||||
key=ns_parser.key, persist=True, show_output=True
|
||||
)
|
||||
```
|
||||
@@ -1270,7 +1156,6 @@ The convention is as follows:
|
||||
"candle": [],
|
||||
"load": [
|
||||
"YahooFinance",
|
||||
"IEXCloud",
|
||||
"AlphaVantage",
|
||||
"Polygon",
|
||||
"EODHD"
|
||||
@@ -1300,7 +1185,7 @@ The way to interpret this file is by following the path to a data source, e.g.
|
||||
|
||||
- `stocks/search` relies on `FinanceDatabase`
|
||||
- `stocks/candle` does not rely on any data source. This means that it relies on data that has been loaded before.
|
||||
- `stocks/load` relies on `YahooFinance`, `IEXCloud`, `AlphaVantage`, `Polygon` or `EODHD`.
|
||||
- `stocks/load` relies on `YahooFinance`, `AlphaVantage`, `Polygon` or `EODHD`.
|
||||
- **The order is important as the first data source is the one utilized by default.**
|
||||
- `stoks/options/unu` relies on `FDScanner`.
|
||||
- `stocks/options/exp` relies on `YahooFinance` by default but `Tradier` and `Nasdaq` sources are allowed.
|
||||
|
||||
5
build/conda/conda-3-8-env-full.yaml
vendored
5
build/conda/conda-3-8-env-full.yaml
vendored
@@ -4,5 +4,6 @@ channels:
|
||||
dependencies:
|
||||
- python=3.8
|
||||
- pip
|
||||
- poetry=1.1.13
|
||||
- lightgbm=3.3.3
|
||||
- conda-forge::lightgbm=3.3.3
|
||||
- pip:
|
||||
- poetry==1.3.2
|
||||
|
||||
3
build/conda/conda-3-8-env.yaml
vendored
3
build/conda/conda-3-8-env.yaml
vendored
@@ -4,4 +4,5 @@ channels:
|
||||
dependencies:
|
||||
- python=3.8
|
||||
- pip
|
||||
- poetry=1.1.13
|
||||
- pip:
|
||||
- poetry==1.3.2
|
||||
|
||||
7
build/conda/conda-3-9-env-full.yaml
vendored
7
build/conda/conda-3-9-env-full.yaml
vendored
@@ -2,7 +2,8 @@ channels:
|
||||
- conda-forge
|
||||
- defaults
|
||||
dependencies:
|
||||
- python=3.9.6
|
||||
- python=3.9.13
|
||||
- pip
|
||||
- poetry=1.1.13
|
||||
- lightgbm=3.3.3
|
||||
- conda-forge::lightgbm=3.3.3
|
||||
- pip:
|
||||
- poetry==1.3.2
|
||||
|
||||
5
build/conda/conda-3-9-env.yaml
vendored
5
build/conda/conda-3-9-env.yaml
vendored
@@ -2,6 +2,7 @@ channels:
|
||||
- conda-forge
|
||||
- defaults
|
||||
dependencies:
|
||||
- python=3.9
|
||||
- python=3.9.13
|
||||
- pip
|
||||
- poetry=1.1.13
|
||||
- pip:
|
||||
- poetry==1.3.2
|
||||
|
||||
8
build/conda/conda-3-9-windows.yaml
vendored
Normal file
8
build/conda/conda-3-9-windows.yaml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
channels:
|
||||
- conda-forge
|
||||
- defaults
|
||||
dependencies:
|
||||
- python=3.9
|
||||
- poetry==1.3.2
|
||||
- setuptools=64.0.2
|
||||
- pip
|
||||
2
build/docker/compose.env
vendored
2
build/docker/compose.env
vendored
@@ -1,2 +1,2 @@
|
||||
OPENBBTERMINAL_DOCKER_REGISTRY="ghcr.io"
|
||||
OPENBBTERMINAL_DOCKER_RELEASE_VERSION="2.3.1"
|
||||
OPENBBTERMINAL_DOCKER_RELEASE_VERSION="2.4.0"
|
||||
|
||||
2
build/docker/docker-compose.yaml
vendored
2
build/docker/docker-compose.yaml
vendored
@@ -7,6 +7,6 @@ services:
|
||||
- ~/OpenBBUserData:/home/python/OpenBBUserData
|
||||
- ~/.openbb_terminal:/home/python/.openbb_terminal
|
||||
platform: linux/amd64
|
||||
image: ghcr.io/openbb-finance/openbbterminal/openbb:2.3.1
|
||||
image: ghcr.io/openbb-finance/openbbterminal/openbb:2.4.0
|
||||
stdin_open: true # docker run -i
|
||||
tty: true # docker run -t
|
||||
|
||||
2
build/docker/openbb.dockerfile
vendored
2
build/docker/openbb.dockerfile
vendored
@@ -40,7 +40,7 @@ FROM debian as poetry
|
||||
ENV PATH="/home/python/.local/bin:${PATH}"
|
||||
|
||||
RUN pip install --upgrade pip wheel
|
||||
RUN pip install poetry==1.1.15
|
||||
RUN pip install poetry==1.3.2
|
||||
|
||||
# SETUP OPENBB IMAGE
|
||||
FROM poetry as repository
|
||||
|
||||
139
build/nsis/setup.nsi
vendored
139
build/nsis/setup.nsi
vendored
@@ -10,7 +10,7 @@
|
||||
!define NAME "OpenBB Terminal"
|
||||
!define COMPANY "OpenBB"
|
||||
!define APPFILE "OpenBBTerminal.exe"
|
||||
!define VERSION "2.3.1"
|
||||
!define VERSION "2.4.0"
|
||||
!define SLUG "${NAME} v${VERSION}"
|
||||
|
||||
;--------------------------------
|
||||
@@ -30,6 +30,7 @@
|
||||
!define MUI_HEADERIMAGE_BITMAP "assets\installer_horizontal.bmp"
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_WELCOMEPAGE_TITLE "${SLUG} Setup"
|
||||
!define UninstId "OpenBBTerminal" ; You might want to use a GUID here
|
||||
|
||||
;--------------------------------
|
||||
; Pages
|
||||
@@ -49,15 +50,145 @@
|
||||
; Set UI language
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
|
||||
Var /GLOBAL installerPath
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; StrContains
|
||||
; This function does a case sensitive searches for an occurrence of a substring in a string.
|
||||
; It returns the substring if it is found.
|
||||
; Otherwise it returns null("").
|
||||
; Written by kenglish_hi
|
||||
; Adapted from StrReplace written by dandaman32
|
||||
|
||||
|
||||
Var STR_HAYSTACK
|
||||
Var STR_NEEDLE
|
||||
Var STR_CONTAINS_VAR_1
|
||||
Var STR_CONTAINS_VAR_2
|
||||
Var STR_CONTAINS_VAR_3
|
||||
Var STR_CONTAINS_VAR_4
|
||||
Var STR_RETURN_VAR
|
||||
|
||||
Function StrContains
|
||||
Exch $STR_NEEDLE
|
||||
Exch 1
|
||||
Exch $STR_HAYSTACK
|
||||
; Uncomment to debug
|
||||
;MessageBox MB_OK 'STR_NEEDLE = $STR_NEEDLE STR_HAYSTACK = $STR_HAYSTACK '
|
||||
StrCpy $STR_RETURN_VAR ""
|
||||
StrCpy $STR_CONTAINS_VAR_1 -1
|
||||
StrLen $STR_CONTAINS_VAR_2 $STR_NEEDLE
|
||||
StrLen $STR_CONTAINS_VAR_4 $STR_HAYSTACK
|
||||
loop:
|
||||
IntOp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_1 + 1
|
||||
StrCpy $STR_CONTAINS_VAR_3 $STR_HAYSTACK $STR_CONTAINS_VAR_2 $STR_CONTAINS_VAR_1
|
||||
StrCmp $STR_CONTAINS_VAR_3 $STR_NEEDLE found
|
||||
StrCmp $STR_CONTAINS_VAR_1 $STR_CONTAINS_VAR_4 done
|
||||
Goto loop
|
||||
found:
|
||||
StrCpy $STR_RETURN_VAR $STR_NEEDLE
|
||||
Goto done
|
||||
done:
|
||||
Pop $STR_NEEDLE ;Prevent "invalid opcode" errors and keep the
|
||||
Exch $STR_RETURN_VAR
|
||||
FunctionEnd
|
||||
|
||||
!macro _StrContainsConstructor OUT NEEDLE HAYSTACK
|
||||
Push `${HAYSTACK}`
|
||||
Push `${NEEDLE}`
|
||||
Call StrContains
|
||||
Pop `${OUT}`
|
||||
!macroend
|
||||
|
||||
!define StrContains '!insertmacro "_StrContainsConstructor"'
|
||||
|
||||
|
||||
;-------------------------------
|
||||
; Uninstall Previous Version if exists
|
||||
|
||||
!macro UninstallExisting exitcode uninstcommand
|
||||
Push `${uninstcommand}`
|
||||
Call UninstallExisting
|
||||
Pop ${exitcode}
|
||||
!macroend
|
||||
Function UninstallExisting
|
||||
Exch $1 ; uninstcommand
|
||||
Push $2 ; Uninstaller
|
||||
Push $3 ; Len
|
||||
StrCpy $3 ""
|
||||
StrCpy $2 $1 1
|
||||
StrCmp $2 '"' qloop sloop
|
||||
sloop:
|
||||
StrCpy $2 $1 1 $3
|
||||
IntOp $3 $3 + 1
|
||||
StrCmp $2 "" +2
|
||||
StrCmp $2 ' ' 0 sloop
|
||||
IntOp $3 $3 - 1
|
||||
Goto run
|
||||
qloop:
|
||||
StrCmp $3 "" 0 +2
|
||||
StrCpy $1 $1 "" 1 ; Remove initial quote
|
||||
IntOp $3 $3 + 1
|
||||
StrCpy $2 $1 1 $3
|
||||
StrCmp $2 "" +2
|
||||
StrCmp $2 '"' 0 qloop
|
||||
run:
|
||||
StrCpy $2 $1 $3 ; Path to uninstaller
|
||||
StrCpy $1 161 ; ERROR_BAD_PATHNAME
|
||||
GetFullPathName $3 "$2\.." ; $InstDir
|
||||
IfFileExists "$2" 0 +4
|
||||
ExecWait '"$2" /S _?=$3' $1 ; This assumes the existing uninstaller is a NSIS uninstaller, other uninstallers don't support /S nor _?=
|
||||
IntCmp $1 0 "" +2 +2 ; Don't delete the installer if it was aborted
|
||||
Delete "$2" ; Delete the uninstaller
|
||||
RMDir "$3" ; Try to delete $InstDir
|
||||
RMDir "$3\.." ; (Optional) Try to delete the parent of $InstDir
|
||||
Pop $3
|
||||
Pop $2
|
||||
Exch $1 ; exitcode
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function .onInit
|
||||
ReadRegStr $0 HKCU "Software\Software\Microsoft\Windows\CurrentVersion\Uninstall\${UninstId}" "UninstallString"
|
||||
${If} $0 != ""
|
||||
${AndIf} ${Cmd} `MessageBox MB_YESNO|MB_ICONQUESTION "It is highly recommended to uninstall the previous version of OpenBB Terminal - Please click Yes to proceed (Note - You will not lose your custom settings) - Or you can uninstall manually. " /SD IDYES IDYES`
|
||||
!insertmacro UninstallExisting $0 $0
|
||||
${If} $0 <> 0
|
||||
MessageBox MB_YESNO|MB_ICONSTOP "Failed to uninstall, continue anyway?" /SD IDYES IDYES +2
|
||||
Abort
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
; Section - Install App
|
||||
|
||||
Section "-hidden app"
|
||||
SectionIn RO
|
||||
SetOutPath "$INSTDIR"
|
||||
${StrContains} $0 "\OpenBB" "$INSTDIR"
|
||||
; Making sure here if user manually removes \openbb from their path that it still installs there
|
||||
; so we dont have issues with uninstaller later.
|
||||
StrCmp $0 "" notfound
|
||||
; MessageBox MB_OK 'Found string $0 $INSTDIR'
|
||||
SetOutPath "$INSTDIR"
|
||||
Goto done
|
||||
notfound:
|
||||
; MessageBox MB_OK "$INSTDIR is 'bla'"
|
||||
SetOutPath "$INSTDIR\OpenBB"
|
||||
StrCpy $InstDir "$INSTDIR\OpenBB"
|
||||
; MessageBox MB_OK 'Did not find string "$INSTDIR\OpenBB" "$installerPath"'
|
||||
done:
|
||||
|
||||
File /r "app\*.*"
|
||||
WriteRegStr HKCU "Software\${NAME}" "" $INSTDIR
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
WriteRegStr HKCU "Software\Software\Microsoft\Windows\CurrentVersion\Uninstall\${UninstId}" "OpenBBTerminal" "OpenBB"
|
||||
WriteRegStr HKCU "Software\Software\Microsoft\Windows\CurrentVersion\Uninstall\${UninstId}" "UninstallString" '"$InstDir\Uninstall.exe"'
|
||||
WriteRegStr HKCU "Software\Software\Microsoft\Windows\CurrentVersion\Uninstall\${UninstId}" "QuietUninstallString" '"$InstDir\Uninstall.exe" /S'
|
||||
SectionEnd
|
||||
|
||||
|
||||
@@ -109,9 +240,13 @@ Section "Uninstall"
|
||||
;Delete Directory
|
||||
Delete '$SMPROGRAMS\${Company}\${NAME}'
|
||||
|
||||
;Delete Reg Key
|
||||
DeleteRegKey HKCU "Software\Software\Microsoft\Windows\CurrentVersion\Uninstall\${UninstId}"
|
||||
|
||||
;Delete Uninstall
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
|
||||
|
||||
;Delete Folder
|
||||
RMDir /r "$INSTDIR"
|
||||
${RMDirUP} "$INSTDIR"
|
||||
|
||||
2
build/pyinstaller/.env
vendored
2
build/pyinstaller/.env
vendored
@@ -1,5 +1,5 @@
|
||||
OPENBB_LOGGING_APP_NAME=gst_packaged
|
||||
OPENBB_LOGGING_COMMIT_HASH=sha:dbd2097
|
||||
OPENBB_LOGGING_COMMIT_HASH=sha:5705675
|
||||
OPENBB_ENABLE_PREDICT=false
|
||||
OPENBB_ENABLE_CHECK_API=true
|
||||
OPENBB_ENABLE_THOUGHTS_DAY=false
|
||||
|
||||
6
build/pyinstaller/terminal.spec
vendored
6
build/pyinstaller/terminal.spec
vendored
@@ -69,10 +69,6 @@ added_files = [
|
||||
os.path.join(pathex, "statsmodels", "datasets"),
|
||||
os.path.join("statsmodels", "datasets"),
|
||||
),
|
||||
(
|
||||
os.path.join(pathex, "investpy", "resources"),
|
||||
os.path.join("investpy", "resources"),
|
||||
),
|
||||
(
|
||||
os.path.join(pathex, "debugpy", "_vendored"),
|
||||
os.path.join("debugpy", "_vendored"),
|
||||
@@ -85,6 +81,7 @@ if is_win:
|
||||
added_files.append(
|
||||
(os.path.join(f"{os.path.dirname(scipy.__file__)}.libs"), "scipy.libs/"),
|
||||
)
|
||||
|
||||
# Python libraries that are explicitly pulled into the bundle
|
||||
hidden_imports = [
|
||||
"sklearn.utils._cython_blas",
|
||||
@@ -103,7 +100,6 @@ hidden_imports = [
|
||||
"user_agent",
|
||||
"vaderSentiment",
|
||||
"frozendict",
|
||||
"textwrap3",
|
||||
"pyEX",
|
||||
"feedparser",
|
||||
"_sysconfigdata__darwin_darwin",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""Check reserved command arguments in Controllers"""
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
from typing import Optional, Any
|
||||
import sys
|
||||
from typing import Any, Optional
|
||||
|
||||
RESERVED_ARGS = {
|
||||
"f": "file",
|
||||
|
||||
55
jupyterlab/README.md
vendored
55
jupyterlab/README.md
vendored
@@ -1,55 +0,0 @@
|
||||
# Jupyter Ecosystem integration
|
||||
|
||||
The Jupyter ecosystem has created Open Source tools that have become the de-facto
|
||||
standard for data related tasks.
|
||||
|
||||
This folder contains source code for a bunch of tools that help using the functionality
|
||||
of the terminal in connection with Jupyter:
|
||||
|
||||
1. Jupyter Lab Extensions for using OpenBB Terminal
|
||||
|
||||
## 1. Jupyter Lab Extensions for using OpenBB Terminal
|
||||
|
||||
Documentation, OpenBB and GOpenBB-settings are 3 Jupyter Lab extensions that illustrate how
|
||||
the terminal can be integrated with Jupyter Lab based IDEs.
|
||||
|
||||
_NOTE: The extensions should be considered prototypes and are not production-ready._
|
||||
|
||||
1. Only bash is supported (only macOS, Linux and WSL). No support for Windows powershell or command prompt.
|
||||
2. The input values are not escaped
|
||||
|
||||
### Installation
|
||||
|
||||
To install the Terminal Launcher and the Settings Extensions run the following commands from the [root folder of the project](/):
|
||||
|
||||
```bash
|
||||
pip install jupyterlab/openbb
|
||||
pip install jupyterlab/openbb-settings
|
||||
pip install jupyterlab/documentation
|
||||
jupyter labextension install jupyterlab/openbb
|
||||
jupyter labextension install jupyterlab/openbb-settings
|
||||
jupyter labextension install jupyterlab/documentation
|
||||
```
|
||||
|
||||
### Development setup
|
||||
|
||||
In this section `openbb` extension will be used as an example.
|
||||
|
||||
- In one terminal window `cd` into the launcher extension folder and build the extension:
|
||||
|
||||
```bash
|
||||
cd openbb
|
||||
jlpm
|
||||
pip install -e .
|
||||
jlpm run build
|
||||
jupyter labextension develop . --overwrite
|
||||
jlpm run watch
|
||||
```
|
||||
|
||||
- In the second tab run jupyter lab
|
||||
|
||||
```bash
|
||||
jupyter lab
|
||||
```
|
||||
|
||||
---
|
||||
5
jupyterlab/documentation/.eslintignore
vendored
5
jupyterlab/documentation/.eslintignore
vendored
@@ -1,5 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
coverage
|
||||
**/*.d.ts
|
||||
ui-tests
|
||||
53
jupyterlab/documentation/.eslintrc.js
vendored
53
jupyterlab/documentation/.eslintrc.js
vendored
@@ -1,53 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:react/recommended',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'jsdoc'],
|
||||
rules: {
|
||||
'@typescript-eslint/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: 'interface',
|
||||
format: ['PascalCase'],
|
||||
custom: {
|
||||
regex: '^I[A-Z]',
|
||||
match: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/quotes': [
|
||||
'error',
|
||||
'single',
|
||||
{ avoidEscape: true, allowTemplateLiterals: false },
|
||||
],
|
||||
curly: ['error', 'all'],
|
||||
eqeqeq: 'error',
|
||||
'jsdoc/require-param-type': 'off',
|
||||
'jsdoc/require-property-type': 'off',
|
||||
'jsdoc/require-returns-type': 'off',
|
||||
'jsdoc/no-types': 'warn',
|
||||
'prefer-arrow-callback': 'error',
|
||||
},
|
||||
settings: {
|
||||
jsdoc: {
|
||||
mode: 'typescript',
|
||||
},
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
};
|
||||
22
jupyterlab/documentation/MANIFEST.in
vendored
22
jupyterlab/documentation/MANIFEST.in
vendored
@@ -1,22 +0,0 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include pyproject.toml
|
||||
include jupyter-config/openbb_terminal_documentation.json
|
||||
|
||||
include package.json
|
||||
include ts*.json
|
||||
|
||||
graft openbb_terminal_documentation/labextension
|
||||
|
||||
# Javascript files
|
||||
graft src
|
||||
graft style
|
||||
prune **/node_modules
|
||||
prune lib
|
||||
|
||||
# Patterns to exclude from any directory
|
||||
global-exclude *~
|
||||
global-exclude *.pyc
|
||||
global-exclude *.pyo
|
||||
global-exclude .git
|
||||
global-exclude .ipynb_checkpoints
|
||||
17
jupyterlab/documentation/README.md
vendored
17
jupyterlab/documentation/README.md
vendored
@@ -1,17 +0,0 @@
|
||||
# OpenBB Terminal Documentation
|
||||
|
||||
This extensions adds a button into the OpenBB Terminal category of the Jupyter Lab launcher panel.
|
||||
|
||||
## Install, Use and Develop
|
||||
|
||||
```bash
|
||||
pip install -e .
|
||||
jlpm
|
||||
jlpm run build:prod
|
||||
jupyter labextension install .
|
||||
|
||||
# Rebuild Typescript source after making changes
|
||||
jlpm build
|
||||
# Rebuild JupyterLab after making any changes
|
||||
jupyter lab build
|
||||
```
|
||||
3
jupyterlab/documentation/RELEASE.md
vendored
3
jupyterlab/documentation/RELEASE.md
vendored
@@ -1,3 +0,0 @@
|
||||
# Making a new release of gamestonk-settings
|
||||
|
||||
Check out the [workflow documentation](https://github.com/jupyter-server/jupyter_releaser#typical-workflow) for information.
|
||||
5
jupyterlab/documentation/install.json
vendored
5
jupyterlab/documentation/install.json
vendored
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"packageManager": "python",
|
||||
"packageName": "openbb_terminal_documentation",
|
||||
"uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package openbb_terminal_documentation"
|
||||
}
|
||||
87
jupyterlab/documentation/package.json
vendored
87
jupyterlab/documentation/package.json
vendored
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"name": "@gamestonk/documentation",
|
||||
"version": "0.1.0",
|
||||
"description": "Gamestonk terminal documentation",
|
||||
"keywords": [
|
||||
"jupyter",
|
||||
"jupyterlab",
|
||||
"jupyterlab-extension"
|
||||
],
|
||||
"homepage": "https://github.com/OpenBB-finance/OpenBBTerminal",
|
||||
"bugs": {
|
||||
"url": "https://github.com/OpenBB-finance/OpenBBTerminal/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Project Jupyter Contributors",
|
||||
"email": "dro.lopes@campus.fct.unl.pt"
|
||||
},
|
||||
"files": [
|
||||
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
||||
"style/**/*.{css,eot,js,gif,html,jpg,json,png,svg,woff2,ttf}",
|
||||
"schema/**/*.json"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"style": "style/index.css",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/OpenBB-finance/OpenBBTerminal.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
|
||||
"build:all": "jlpm run build:lib && jlpm run build:labextension",
|
||||
"build:labextension": "jupyter labextension build .",
|
||||
"build:labextension:dev": "jupyter labextension build --development True .",
|
||||
"build:lib": "tsc",
|
||||
"build:prod": "jlpm run clean && jlpm run build:lib && jlpm run build:labextension",
|
||||
"clean": "jlpm run clean:lib",
|
||||
"clean:all": "jlpm run clean:lib && jlpm run clean:labextension",
|
||||
"clean:labextension": "rimraf openbb_terminal_documentation/labextension",
|
||||
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
||||
"eslint": "eslint . --ext .ts,.tsx --fix",
|
||||
"eslint:check": "eslint . --ext .ts,.tsx",
|
||||
"install:extension": "jlpm run build",
|
||||
"prepare": "jlpm run clean && jlpm run build:prod",
|
||||
"watch": "run-p watch:src watch:labextension",
|
||||
"watch:labextension": "jupyter labextension watch .",
|
||||
"watch:src": "tsc -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyterlab/application": "^3.2.8",
|
||||
"@jupyterlab/launcher": "^3.2.8",
|
||||
"@jupyterlab/mainmenu": "^3.2.8",
|
||||
"marked": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jupyterlab/builder": "^3.2.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-jsdoc": "^37.6.3",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "<4.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "^0.4.0",
|
||||
"marked": "^4.0.10",
|
||||
"got": "^11.8.5",
|
||||
"jpeg-js": "^0.4.4"
|
||||
},
|
||||
"sideEffects": [
|
||||
"style/*.css",
|
||||
"style/*.svg",
|
||||
"style/index.js"
|
||||
],
|
||||
"jupyterlab": {
|
||||
"extension": true,
|
||||
"outputDir": "openbb_terminal_documentation/labextension",
|
||||
"schemaDir": "schema"
|
||||
},
|
||||
"styleModule": "style/index.js"
|
||||
}
|
||||
17
jupyterlab/documentation/pyproject.toml
vendored
17
jupyterlab/documentation/pyproject.toml
vendored
@@ -1,17 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.1"]
|
||||
build-backend = "jupyter_packaging.build_api"
|
||||
|
||||
[tool.jupyter-packaging.options]
|
||||
skip-if-exists = ["openbb_terminal_documentation/labextension/static/style.js"]
|
||||
ensured-targets = ["openbb_terminal_documentation/labextension/static/style.js", "openbb_terminal_documentation/labextension/package.json"]
|
||||
|
||||
[tool.jupyter-packaging.builder]
|
||||
factory = "jupyter_packaging.npm_builder"
|
||||
|
||||
[tool.jupyter-packaging.build-args]
|
||||
build_cmd = "build:prod"
|
||||
npm = ["jlpm"]
|
||||
|
||||
[tool.check-manifest]
|
||||
ignore = ["openbb_terminal_documentation/labextension/**", "yarn.lock", ".*", "package-lock.json"]
|
||||
25
jupyterlab/documentation/schema/plugin.json
vendored
25
jupyterlab/documentation/schema/plugin.json
vendored
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"title": "OpenBB Terminal Documentation",
|
||||
"description": "OpenBB Terminal Documentation.",
|
||||
"jupyter.lab.menus": {
|
||||
"main": [
|
||||
{
|
||||
"id": "jp-mainmenu-file",
|
||||
"items": [
|
||||
{
|
||||
"type": "submenu",
|
||||
"id": "jp-mainmenu-file-new",
|
||||
"items": [
|
||||
{
|
||||
"command": "gamestonk:documentation",
|
||||
"rank": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
"""
|
||||
openbb_terminal_documentation setup
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import setuptools
|
||||
|
||||
HERE = Path(__file__).parent.resolve()
|
||||
|
||||
# The name of the project
|
||||
name = "openbb_terminal_documentation"
|
||||
|
||||
lab_path = HERE / name.replace("-", "_") / "labextension"
|
||||
|
||||
# Representative files that should exist after a successful build
|
||||
ensured_targets = [str(lab_path / "package.json"), str(lab_path / "static/style.js")]
|
||||
|
||||
labext_name = "@gamestonk/documentation"
|
||||
|
||||
data_files_spec = [
|
||||
(
|
||||
"share/jupyter/labextensions/%s" % labext_name,
|
||||
str(lab_path.relative_to(HERE)),
|
||||
"**",
|
||||
),
|
||||
("share/jupyter/labextensions/%s" % labext_name, ".", "install.json"),
|
||||
]
|
||||
|
||||
long_description = (HERE / "README.md").read_text()
|
||||
|
||||
# Get the package info from package.json
|
||||
pkg_json = json.loads((HERE / "package.json").read_bytes())
|
||||
|
||||
setup_args = dict(
|
||||
name=name,
|
||||
version=pkg_json["version"],
|
||||
url=pkg_json["homepage"],
|
||||
author=pkg_json["author"]["name"],
|
||||
author_email=pkg_json["author"]["email"],
|
||||
description=pkg_json["description"],
|
||||
license=pkg_json["license"],
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages(),
|
||||
install_requires=[],
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
python_requires=">=3.6",
|
||||
platforms="Linux, Mac OS X, Windows",
|
||||
keywords=["Jupyter", "JupyterLab", "JupyterLab3"],
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Framework :: Jupyter",
|
||||
],
|
||||
)
|
||||
|
||||
try:
|
||||
from jupyter_packaging import wrap_installers, npm_builder, get_data_files
|
||||
|
||||
post_develop = npm_builder(
|
||||
build_cmd="install:extension", source_dir="src", build_dir=lab_path
|
||||
)
|
||||
setup_args["cmdclass"] = wrap_installers(
|
||||
post_develop=post_develop, ensured_targets=ensured_targets
|
||||
)
|
||||
setup_args["data_files"] = get_data_files(data_files_spec)
|
||||
except ImportError as e:
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format="%(levelname)s: %(message)s")
|
||||
logging.warning(
|
||||
"Build tool `jupyter-packaging` is missing. Install it with pip or conda."
|
||||
)
|
||||
if not ("--name" in sys.argv or "--version" in sys.argv):
|
||||
raise e
|
||||
|
||||
if __name__ == "__main__":
|
||||
setuptools.setup(**setup_args)
|
||||
77
jupyterlab/documentation/src/index.ts
vendored
77
jupyterlab/documentation/src/index.ts
vendored
@@ -1,77 +0,0 @@
|
||||
import {
|
||||
JupyterFrontEnd,
|
||||
JupyterFrontEndPlugin,
|
||||
} from '@jupyterlab/application';
|
||||
|
||||
import { ICommandPalette } from '@jupyterlab/apputils';
|
||||
|
||||
import { ILauncher } from '@jupyterlab/launcher';
|
||||
|
||||
import { IMainMenu } from "@jupyterlab/mainmenu";
|
||||
|
||||
import { LabIcon } from '@jupyterlab/ui-components';
|
||||
|
||||
import docsIconStr from '../style/docs.svg';
|
||||
|
||||
const CATEGORY = "OpenBB Terminal";
|
||||
|
||||
namespace CommandIDs {
|
||||
export const createNew = 'jlab-examples:create-new-python-file';
|
||||
}
|
||||
|
||||
const extension: JupyterFrontEndPlugin<void> = {
|
||||
id: 'documentation',
|
||||
autoStart: true,
|
||||
optional: [ILauncher, ICommandPalette],
|
||||
activate: (
|
||||
app: JupyterFrontEnd,
|
||||
launcher: ILauncher | null,
|
||||
menu: IMainMenu | null,
|
||||
palette: ICommandPalette | null
|
||||
) => {
|
||||
const { commands } = app;
|
||||
const command = CommandIDs.createNew;
|
||||
const icon = new LabIcon({
|
||||
name: 'documentation:docs-icon',
|
||||
svgstr: docsIconStr,
|
||||
});
|
||||
|
||||
commands.addCommand(command, {
|
||||
label: 'Gamestonk Documentation',
|
||||
icon: icon,
|
||||
execute: (args: any) => {
|
||||
window.open(
|
||||
'https://openbb-finance.github.io/OpenBBTerminal/',
|
||||
'_blank'
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
// Add the command to the launcher
|
||||
if (launcher) {
|
||||
launcher.add({
|
||||
command,
|
||||
category: CATEGORY,
|
||||
rank: 3,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the palette
|
||||
if (palette) {
|
||||
palette.addItem({
|
||||
command,
|
||||
args: { isPalette: true },
|
||||
category: CATEGORY,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the menu
|
||||
if (menu) {
|
||||
menu.fileMenu.newMenu.addGroup([{ command }], 30);
|
||||
}
|
||||
console.log("Added Gamestonk Settings Extension.");
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
export default extension;
|
||||
4
jupyterlab/documentation/src/svg.d.ts
vendored
4
jupyterlab/documentation/src/svg.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
declare module '*.svg' {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
9
jupyterlab/documentation/style/docs.svg
vendored
9
jupyterlab/documentation/style/docs.svg
vendored
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>docs</title>
|
||||
<g id="docs" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle" fill="#424242" x="15" y="18" width="225" height="220"></rect>
|
||||
<path d="M128.5,67.5 C121.320298,67.5 115.5,73.3202983 115.5,80.5 C115.5,87.6797017 121.320298,93.5 128.5,93.5 C135.679702,93.5 141.5,87.6797017 141.5,80.5 C141.5,77.0521856 140.130361,73.7455848 137.692388,71.3076118 C135.254415,68.8696389 131.947814,67.5 128.5,67.5 Z" id="Path" stroke="#FFFFFF" stroke-width="10" fill-rule="nonzero"></path>
|
||||
<rect id="Rectangle" fill="#FFFFFF" x="115.652174" y="108" width="25.7391304" height="74" rx="12"></rect>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 866 B |
1
jupyterlab/documentation/style/index.css
vendored
1
jupyterlab/documentation/style/index.css
vendored
@@ -1 +0,0 @@
|
||||
@import url('base.css');
|
||||
1
jupyterlab/documentation/style/index.js
vendored
1
jupyterlab/documentation/style/index.js
vendored
@@ -1 +0,0 @@
|
||||
import './base.css';
|
||||
24
jupyterlab/documentation/tsconfig.json
vendored
24
jupyterlab/documentation/tsconfig.json
vendored
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"incremental": true,
|
||||
"jsx": "react",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true,
|
||||
"preserveWatchOutput": true,
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "lib",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"strictNullChecks": false,
|
||||
"target": "es2017",
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/*"]
|
||||
}
|
||||
6149
jupyterlab/documentation/yarn.lock
vendored
6149
jupyterlab/documentation/yarn.lock
vendored
File diff suppressed because it is too large
Load Diff
5
jupyterlab/openbb-settings/.eslintignore
vendored
5
jupyterlab/openbb-settings/.eslintignore
vendored
@@ -1,5 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
coverage
|
||||
**/*.d.ts
|
||||
ui-tests
|
||||
54
jupyterlab/openbb-settings/.eslintrc.js
vendored
54
jupyterlab/openbb-settings/.eslintrc.js
vendored
@@ -1,54 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:react/recommended',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'jsdoc'],
|
||||
rules: {
|
||||
"react/react-in-jsx-scope": "off",
|
||||
'@typescript-eslint/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: 'interface',
|
||||
format: ['PascalCase'],
|
||||
custom: {
|
||||
regex: '^I[A-Z]',
|
||||
match: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/quotes': [
|
||||
'error',
|
||||
'double',
|
||||
{ avoidEscape: true, allowTemplateLiterals: false },
|
||||
],
|
||||
curly: ['error', 'all'],
|
||||
eqeqeq: 'error',
|
||||
'jsdoc/require-param-type': 'off',
|
||||
'jsdoc/require-property-type': 'off',
|
||||
'jsdoc/require-returns-type': 'off',
|
||||
'jsdoc/no-types': 'warn',
|
||||
'prefer-arrow-callback': 'error',
|
||||
},
|
||||
settings: {
|
||||
jsdoc: {
|
||||
mode: 'typescript',
|
||||
},
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
};
|
||||
22
jupyterlab/openbb-settings/MANIFEST.in
vendored
22
jupyterlab/openbb-settings/MANIFEST.in
vendored
@@ -1,22 +0,0 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include pyproject.toml
|
||||
include jupyter-config/openbb_terminal_settings.json
|
||||
|
||||
include package.json
|
||||
include ts*.json
|
||||
|
||||
graft openbb_terminal_settings/labextension
|
||||
|
||||
# Javascript files
|
||||
graft src
|
||||
graft style
|
||||
prune **/node_modules
|
||||
prune lib
|
||||
|
||||
# Patterns to exclude from any directory
|
||||
global-exclude *~
|
||||
global-exclude *.pyc
|
||||
global-exclude *.pyo
|
||||
global-exclude .git
|
||||
global-exclude .ipynb_checkpoints
|
||||
17
jupyterlab/openbb-settings/README.md
vendored
17
jupyterlab/openbb-settings/README.md
vendored
@@ -1,17 +0,0 @@
|
||||
# OpenBB Terminal Settings Menu
|
||||
|
||||
This extensions allows the user to set API keys and feature flags for the OpenBB Terminal
|
||||
|
||||
## Install, Use and Develop
|
||||
|
||||
```bash
|
||||
pip install -e .
|
||||
jlpm
|
||||
jlpm run build:prod
|
||||
jupyter labextension install .
|
||||
|
||||
# Rebuild Typescript source after making changes
|
||||
jlpm build
|
||||
# Rebuild JupyterLab after making any changes
|
||||
jupyter lab build
|
||||
```
|
||||
3
jupyterlab/openbb-settings/RELEASE.md
vendored
3
jupyterlab/openbb-settings/RELEASE.md
vendored
@@ -1,3 +0,0 @@
|
||||
# Making a new release of gamestonk-settings
|
||||
|
||||
Check out the [workflow documentation](https://github.com/jupyter-server/jupyter_releaser#typical-workflow) for information.
|
||||
5
jupyterlab/openbb-settings/install.json
vendored
5
jupyterlab/openbb-settings/install.json
vendored
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"packageManager": "python",
|
||||
"packageName": "openbb_terminal_settings",
|
||||
"uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package openbb_terminal_settings"
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import json
|
||||
import os.path as osp
|
||||
|
||||
from ._version import __version__ # noqa: F401
|
||||
|
||||
HERE = osp.abspath(osp.dirname(__file__))
|
||||
|
||||
with open(osp.join(HERE, "labextension", "package.json")) as fid:
|
||||
data = json.load(fid)
|
||||
|
||||
|
||||
def _jupyter_labextension_paths():
|
||||
return [{"src": "labextension", "dest": data["name"]}]
|
||||
@@ -1,2 +0,0 @@
|
||||
version_info = (0, 1, 0)
|
||||
__version__ = ".".join(map(str, version_info))
|
||||
89
jupyterlab/openbb-settings/package.json
vendored
89
jupyterlab/openbb-settings/package.json
vendored
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"name": "@gamestonk/settings",
|
||||
"version": "0.1.0",
|
||||
"description": "Gamestonk settings launcher",
|
||||
"keywords": [
|
||||
"jupyter",
|
||||
"jupyterlab",
|
||||
"jupyterlab-extension"
|
||||
],
|
||||
"homepage": "https://github.com/OpenBB-finance/OpenBBTerminal",
|
||||
"bugs": {
|
||||
"url": "https://github.com/OpenBB-finance/OpenBBTerminal/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Gamestonk Contributors",
|
||||
"email": "dro.lopes@campus.fct.unl.pt"
|
||||
},
|
||||
"files": [
|
||||
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
||||
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
|
||||
"style/index.js",
|
||||
"schema/**/*.json"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"style": "style/index.css",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jupyterlab/extension-examples.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
|
||||
"build:all": "jlpm run build:lib && jlpm run build:labextension",
|
||||
"build:labextension": "jupyter labextension build .",
|
||||
"build:labextension:dev": "jupyter labextension build --development True .",
|
||||
"build:lib": "tsc",
|
||||
"build:prod": "jlpm run clean && jlpm run build:lib && jlpm run build:labextension",
|
||||
"clean": "jlpm run clean:lib",
|
||||
"clean:all": "jlpm run clean:lib && jlpm run clean:labextension",
|
||||
"clean:labextension": "rimraf openbb_terminal_settings/labextension",
|
||||
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
||||
"eslint": "eslint . --ext .ts,.tsx --fix",
|
||||
"eslint:check": "eslint . --ext .ts,.tsx",
|
||||
"install:extension": "jlpm run build",
|
||||
"prepare": "jlpm run clean && jlpm run build:prod",
|
||||
"watch": "run-p watch:src watch:labextension",
|
||||
"watch:labextension": "jupyter labextension watch .",
|
||||
"watch:src": "tsc -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyterlab/application": "^3.2.8",
|
||||
"@jupyterlab/launcher": "^3.2.8",
|
||||
"@jupyterlab/mainmenu": "^3.2.8",
|
||||
"@jupyterlab/settingregistry": "^3.2.8",
|
||||
"@jupyterlab/ui-components": "^3.2.8",
|
||||
"marked": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jupyterlab/builder": "^3.2.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-jsdoc": "^37.6.3",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "<4.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "^0.4.0",
|
||||
"marked": "^4.0.10",
|
||||
"got": "^11.8.5",
|
||||
"jpeg-js": "^0.4.4"
|
||||
},
|
||||
"sideEffects": [
|
||||
"style/*.css",
|
||||
"style/index.js"
|
||||
],
|
||||
"jupyterlab": {
|
||||
"extension": true,
|
||||
"outputDir": "openbb_terminal_settings/labextension",
|
||||
"schemaDir": "schema"
|
||||
},
|
||||
"styleModule": "style/index.js"
|
||||
}
|
||||
17
jupyterlab/openbb-settings/pyproject.toml
vendored
17
jupyterlab/openbb-settings/pyproject.toml
vendored
@@ -1,17 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.1"]
|
||||
build-backend = "jupyter_packaging.build_api"
|
||||
|
||||
[tool.jupyter-packaging.options]
|
||||
skip-if-exists = ["openbb_terminal_settings/labextension/static/style.js"]
|
||||
ensured-targets = ["openbb_terminal_settings/labextension/static/style.js", "openbb_terminal_settings/labextension/package.json"]
|
||||
|
||||
[tool.jupyter-packaging.builder]
|
||||
factory = "jupyter_packaging.npm_builder"
|
||||
|
||||
[tool.jupyter-packaging.build-args]
|
||||
build_cmd = "build:prod"
|
||||
npm = ["jlpm"]
|
||||
|
||||
[tool.check-manifest]
|
||||
ignore = ["openbb_terminal_settings/labextension/**", "yarn.lock", ".*", "package-lock.json"]
|
||||
392
jupyterlab/openbb-settings/schema/settings.json
vendored
392
jupyterlab/openbb-settings/schema/settings.json
vendored
@@ -1,392 +0,0 @@
|
||||
{
|
||||
"title": "OpenBB settings",
|
||||
"description": "Settings for OpenBB Terminal extension.",
|
||||
"type": "object",
|
||||
"properties":
|
||||
{
|
||||
"FEATURE_FLAGS":
|
||||
{
|
||||
"title": "Feature flags",
|
||||
"description": "Feature flags for the OpenBB Terminal.",
|
||||
"default":
|
||||
{
|
||||
"OPENBB_USE_CLEAR_AFTER_CMD":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Clear after command",
|
||||
"description": "Use clear console after each command",
|
||||
"default": false,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_USE_FLAIR":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "text",
|
||||
"title": "Console flair",
|
||||
"description": "Select console flair (choose from config_terminal.py list)",
|
||||
"default": "openbb",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_USE_ION":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Interactive charts",
|
||||
"description": "Enable interactive matplotlib",
|
||||
"default": true,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_USE_PROMPT_TOOLKIT":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Autocomplete",
|
||||
"description": "Enable Prompt Toolkit",
|
||||
"default": true,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_ENABLE_PREDICT":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Prediction menu",
|
||||
"description": "Enable Prediction features",
|
||||
"default": true,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_USE_PLOT_AUTOSCALING":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Plot autoscaling",
|
||||
"description": "Enable plot autoscaling",
|
||||
"default": false,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_ENABLE_THOUGHTS_DAY":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Thoughts of the day",
|
||||
"description": "Enable thoughts of the day",
|
||||
"default": false,
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_ENABLE_QUICK_EXIT":
|
||||
{
|
||||
"type": "bool",
|
||||
"form": "checkbox",
|
||||
"title": "Quick exit",
|
||||
"description": "Quick exit for testing",
|
||||
"default": false,
|
||||
"value": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"APP_SETTINGS":
|
||||
{
|
||||
"title": "General",
|
||||
"description": "Application settings for the OpenBB Terminal.",
|
||||
"default":
|
||||
{
|
||||
"PAPERMILL_NOTEBOOK_REPORT_PORT":
|
||||
{
|
||||
"type": "number",
|
||||
"form": "number",
|
||||
"title": "Papermill port",
|
||||
"description": "Papermill port",
|
||||
"default": 8892,
|
||||
"value": ""
|
||||
},
|
||||
"PYTHON_BINARY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "text",
|
||||
"title": "Python executable",
|
||||
"description": "Path to the python in your custom environment",
|
||||
"default": "python",
|
||||
"value": ""
|
||||
},
|
||||
"TERMINAL_PATH":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "text",
|
||||
"title": "Terminal path",
|
||||
"description": "Path to the terminal.py",
|
||||
"default": "terminal.py",
|
||||
"value": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"API_KEYS":
|
||||
{
|
||||
"title": "API Keys",
|
||||
"description": "Access credentials for data providers.",
|
||||
"default":
|
||||
{
|
||||
"OPENBB_API_KEY_ALPHAVANTAGE":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Alphavantage",
|
||||
"description": "https://www.alphavantage.co",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_KEY_FINANCIALMODELINGPREP":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "financialmodelingprep",
|
||||
"description": "https://financialmodelingprep.com/developer",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_KEY_QUANDL":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "quandl",
|
||||
"description": "https://www.quandl.com/tools/api",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_REDDIT_CLIENT_ID":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Reddit client ID",
|
||||
"description": "https://www.reddit.com/prefs/apps",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_REDDIT_CLIENT_SECRET":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Reddit client secret",
|
||||
"description": "https://www.reddit.com/prefs/apps",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_REDDIT_USERNAME":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Reddit username",
|
||||
"description": "https://www.reddit.com/prefs/apps",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_REDDIT_USER_AGENT":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Reddit user agent",
|
||||
"description": "https://www.reddit.com/prefs/apps",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_REDDIT_PASSWORD":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Reddit password",
|
||||
"description": "https://www.reddit.com/prefs/apps",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_POLYGON_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Polygon",
|
||||
"description": "https://polygon.io",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_TWITTER_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Twitter key",
|
||||
"description": "https://developer.twitter.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_TWITTER_SECRET_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Twitter secret",
|
||||
"description": "https://developer.twitter.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_TWITTER_BEARER_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Twitter token",
|
||||
"description": "https://developer.twitter.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_FRED_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "FRED",
|
||||
"description": "https://fred.stlouisfed.org/docs/api/api_key.html",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_NEWS_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "NewsAPI",
|
||||
"description": "https://newsapi.org",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_RH_USERNAME":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Robinhood username",
|
||||
"description": "Robinhood",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_RH_PASSWORD":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Robinhood password",
|
||||
"description": "Robinhood",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_DG_USERNAME":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Degiro username",
|
||||
"description": "Degiro",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_DG_PASSWORD":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Degiro password",
|
||||
"description": "Degiro",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_DG_TOTP_SECRET":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Degiro secret",
|
||||
"description": "Degiro",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_OANDA_ACCOUNT_TYPE":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Oanda account type",
|
||||
"description": "https://developer.oanda.com",
|
||||
"default": "practice",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_OANDA_ACCOUNT":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Oanda account",
|
||||
"description": "https://developer.oanda.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_OANDA_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Oanda token",
|
||||
"description": "https://developer.oanda.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_TRADIER_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Tradier token",
|
||||
"description": "https://tradier.com/products/market-data-api",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_CMC_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Coinmarketcap key",
|
||||
"description": "https://coinmarketcap.com/api/",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_BINANCE_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Binance key",
|
||||
"description": "https://www.binance.com/en/",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_BINANCE_SECRET":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Binance secret",
|
||||
"description": "Binance secret",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_FINNHUB_KEY":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Finnhub key",
|
||||
"description": "https://finnhub.io",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_IEX_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "IEX Cloud key",
|
||||
"description": "https://iexcloud.io",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
},
|
||||
"OPENBB_API_SENTIMENTINVESTOR_TOKEN":
|
||||
{
|
||||
"type": "string",
|
||||
"form": "password",
|
||||
"title": "Sentimentinvestor token",
|
||||
"description": "https://www.sentimentinvestor.com",
|
||||
"default": "REPLACE_ME",
|
||||
"value": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
"""
|
||||
openbb_terminal_settings setup
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import setuptools
|
||||
|
||||
HERE = Path(__file__).parent.resolve()
|
||||
|
||||
# The name of the project
|
||||
name = "openbb_terminal_settings"
|
||||
|
||||
lab_path = HERE / name.replace("-", "_") / "labextension"
|
||||
|
||||
# Representative files that should exist after a successful build
|
||||
ensured_targets = [str(lab_path / "package.json"), str(lab_path / "static/style.js")]
|
||||
|
||||
labext_name = "@gamestonk/settings"
|
||||
|
||||
data_files_spec = [
|
||||
(
|
||||
"share/jupyter/labextensions/%s" % labext_name,
|
||||
str(lab_path.relative_to(HERE)),
|
||||
"**",
|
||||
),
|
||||
("share/jupyter/labextensions/%s" % labext_name, ".", "install.json"),
|
||||
]
|
||||
|
||||
long_description = (HERE / "README.md").read_text()
|
||||
|
||||
# Get the package info from package.json
|
||||
pkg_json = json.loads((HERE / "package.json").read_bytes())
|
||||
|
||||
setup_args = dict(
|
||||
name=name,
|
||||
version=pkg_json["version"],
|
||||
url=pkg_json["homepage"],
|
||||
author=pkg_json["author"]["name"],
|
||||
author_email=pkg_json["author"]["email"],
|
||||
description=pkg_json["description"],
|
||||
license=pkg_json["license"],
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages(),
|
||||
install_requires=[],
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
python_requires=">=3.6",
|
||||
platforms="Linux, Mac OS X, Windows",
|
||||
keywords=["Jupyter", "JupyterLab", "JupyterLab3"],
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Framework :: Jupyter",
|
||||
],
|
||||
)
|
||||
|
||||
try:
|
||||
from jupyter_packaging import wrap_installers, npm_builder, get_data_files
|
||||
|
||||
post_develop = npm_builder(
|
||||
build_cmd="install:extension", source_dir="src", build_dir=lab_path
|
||||
)
|
||||
setup_args["cmdclass"] = wrap_installers(
|
||||
post_develop=post_develop, ensured_targets=ensured_targets
|
||||
)
|
||||
setup_args["data_files"] = get_data_files(data_files_spec)
|
||||
except ImportError as e:
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format="%(levelname)s: %(message)s")
|
||||
logging.warning(
|
||||
"Build tool `jupyter-packaging` is missing. Install it with pip or conda."
|
||||
)
|
||||
if not ("--name" in sys.argv or "--version" in sys.argv):
|
||||
raise e
|
||||
|
||||
if __name__ == "__main__":
|
||||
setuptools.setup(**setup_args)
|
||||
@@ -1,58 +0,0 @@
|
||||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* Generic input form
|
||||
*
|
||||
* @class FormInput (name)
|
||||
* @param {} arg1 Arguments
|
||||
* @param {} arg1.itemParent The item parent
|
||||
* @param {} arg1.index The item index
|
||||
* @param {} arg1.onChangeParent On change parent function
|
||||
* @returns {} Gemeric input form
|
||||
*/
|
||||
export default function FormInput({
|
||||
itemParent,
|
||||
index,
|
||||
onChangeParent,
|
||||
}: {
|
||||
itemParent: any;
|
||||
index: number;
|
||||
onChangeParent: any;
|
||||
}): any {
|
||||
const [item, setItem] = useState({
|
||||
key: itemParent.key,
|
||||
value: itemParent.value,
|
||||
});
|
||||
const onChange = (event: any) => {
|
||||
const newValue =
|
||||
event.target.type === "checkbox"
|
||||
? event.target.checked
|
||||
: event.target.value;
|
||||
|
||||
setItem((prevState) => {
|
||||
const value = item.value;
|
||||
value.value = newValue;
|
||||
const newItem = { ...prevState, value: value };
|
||||
onChangeParent(index, newItem);
|
||||
return newItem;
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<label className="inputFieldLabel">{item.value.title}</label>
|
||||
<input
|
||||
className={item.value.title}
|
||||
type={item.value.form}
|
||||
checked={
|
||||
item.value.form === "checkbox"
|
||||
? item.value.value === ""
|
||||
? item.value.default
|
||||
: item.value.value
|
||||
: false
|
||||
}
|
||||
value={item.value.value === "" ? item.value.default : item.value.value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
90
jupyterlab/openbb-settings/src/index.ts
vendored
90
jupyterlab/openbb-settings/src/index.ts
vendored
@@ -1,90 +0,0 @@
|
||||
import {
|
||||
JupyterFrontEnd,
|
||||
JupyterFrontEndPlugin,
|
||||
} from "@jupyterlab/application";
|
||||
|
||||
import { ICommandPalette } from "@jupyterlab/apputils";
|
||||
import { MainAreaWidget } from "@jupyterlab/apputils";
|
||||
|
||||
import { ILauncher } from "@jupyterlab/launcher";
|
||||
import { ISettingRegistry } from "@jupyterlab/settingregistry";
|
||||
|
||||
import { IMainMenu } from "@jupyterlab/mainmenu";
|
||||
|
||||
import { LabIcon } from "@jupyterlab/ui-components";
|
||||
import svgIconStr from "../style/settings-icon.svg";
|
||||
|
||||
import { TerminalSettingsWidget } from "./widget";
|
||||
|
||||
const CATEGORY = "OpenBB Terminal";
|
||||
|
||||
/**
|
||||
* The command IDs used by the Gamestonk Settings plugin.
|
||||
*/
|
||||
namespace CommandIDs {
|
||||
export const create = "gamestonk:settings";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization data for the Gamestonk Settings extension.
|
||||
*/
|
||||
const extension: JupyterFrontEndPlugin<void> = {
|
||||
id: "gst:settings",
|
||||
autoStart: true,
|
||||
optional: [ILauncher, IMainMenu, ICommandPalette, ISettingRegistry],
|
||||
activate: async (
|
||||
app: JupyterFrontEnd,
|
||||
launcher: ILauncher | null,
|
||||
menu: IMainMenu | null,
|
||||
palette: ICommandPalette | null,
|
||||
settings: ISettingRegistry
|
||||
) => {
|
||||
const { commands } = app;
|
||||
|
||||
const command = CommandIDs.create;
|
||||
const icon = new LabIcon({
|
||||
name: "launcher:gst-settings-icon",
|
||||
svgstr: svgIconStr,
|
||||
});
|
||||
|
||||
const s = await settings.load("@gamestonk/settings:settings");
|
||||
|
||||
commands.addCommand(command, {
|
||||
caption: "Edit OpenBB Terminal Settings",
|
||||
label: "Settings",
|
||||
icon: (args) => (args["isPalette"] ? null : icon),
|
||||
execute: () => {
|
||||
const content = new TerminalSettingsWidget(s);
|
||||
const widget = new MainAreaWidget<TerminalSettingsWidget>({ content });
|
||||
widget.title.label = "Gamestonk Settings";
|
||||
widget.title.icon = icon;
|
||||
app.shell.add(widget, "main", { activate: true, mode: "split-right" });
|
||||
},
|
||||
});
|
||||
|
||||
if (launcher) {
|
||||
launcher.add({
|
||||
command,
|
||||
category: CATEGORY,
|
||||
rank: 2,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the palette
|
||||
if (palette) {
|
||||
palette.addItem({
|
||||
command,
|
||||
args: { isPalette: true },
|
||||
category: CATEGORY,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the menu
|
||||
if (menu) {
|
||||
menu.fileMenu.newMenu.addGroup([{ command }], 30);
|
||||
}
|
||||
console.log("Added Gamestonk Settings Extension.");
|
||||
},
|
||||
};
|
||||
|
||||
export default extension;
|
||||
4
jupyterlab/openbb-settings/src/svg.d.ts
vendored
4
jupyterlab/openbb-settings/src/svg.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
declare module '*.svg' {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
189
jupyterlab/openbb-settings/src/widget.tsx
vendored
189
jupyterlab/openbb-settings/src/widget.tsx
vendored
@@ -1,189 +0,0 @@
|
||||
import { ReactWidget } from "@jupyterlab/apputils";
|
||||
import { ISettingRegistry } from "@jupyterlab/settingregistry";
|
||||
import FormInput from "./components/FormInput";
|
||||
|
||||
/**
|
||||
* OpenBB Terminal Settings Menu
|
||||
*
|
||||
* @class GamestonkTerminalSettingsComponent (name)
|
||||
* @param {} root0 - s: Settings object
|
||||
* @param {} root0.s - s: Accessible settings object
|
||||
* @returns {} JSX.Element Settings form component
|
||||
*/
|
||||
export function GamestonkTerminalSettingsComponent({ s }: any): JSX.Element {
|
||||
/**
|
||||
* Get the section settings values.
|
||||
*
|
||||
* The section settings are taken from the user space (`s.user` if section keys
|
||||
* exist there) or from the default values of the settings schema.
|
||||
*
|
||||
* @param section The section name
|
||||
* @returns The state of the section settings.
|
||||
*/
|
||||
function getSectionState(section: string): Record<string, unknown>[] {
|
||||
const values: Array<Record<string, unknown>> = [];
|
||||
Object.keys(s.schema.properties[section].default).forEach((element) => {
|
||||
const settingsValue =
|
||||
typeof s.user[section] === "undefined"
|
||||
? s.schema.properties[section].default[element]
|
||||
: s.user[section][element];
|
||||
values.push({
|
||||
key: element,
|
||||
value: settingsValue,
|
||||
});
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
const featureFlags = getSectionState("FEATURE_FLAGS");
|
||||
const appSettings = getSectionState("APP_SETTINGS");
|
||||
const apiKeys = getSectionState("API_KEYS");
|
||||
|
||||
const onFeatureFlagsChange = (index: any, item: any) => {
|
||||
featureFlags[index] = item;
|
||||
};
|
||||
|
||||
const onAppSettingsChange = (index: any, item: any) => {
|
||||
appSettings[index] = item;
|
||||
};
|
||||
|
||||
const onApiKeysChange = (index: any, item: any) => {
|
||||
apiKeys[index] = item;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param event - Update button click event
|
||||
*/
|
||||
function handleSubmit(event: any) {
|
||||
event.preventDefault();
|
||||
|
||||
const featureFlagsObject = {} as any;
|
||||
featureFlags.forEach((flag: any) => {
|
||||
featureFlagsObject[flag.key] = flag["value"];
|
||||
});
|
||||
s.set("FEATURE_FLAGS", featureFlagsObject);
|
||||
|
||||
const apiKeysObject = {} as any;
|
||||
apiKeys.forEach((apiKey: any) => {
|
||||
apiKeysObject[apiKey.key] = apiKey["value"];
|
||||
});
|
||||
s.set("API_KEYS", apiKeysObject);
|
||||
|
||||
const appSettingsObject = {} as any;
|
||||
appSettings.forEach((appSetting: any) => {
|
||||
appSettingsObject[appSetting.key] = appSetting["value"];
|
||||
});
|
||||
s.set("APP_SETTINGS", appSettingsObject);
|
||||
|
||||
alert("Settings updated.");
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="gamestonkSettings">
|
||||
<div className="settingsForm">
|
||||
<form>
|
||||
<fieldset id="featureFlags">
|
||||
<p className="settingsSectionLabel">Feature Flags</p>
|
||||
<div className="fieldSetData">
|
||||
{featureFlags.map((item: any, index: any) => (
|
||||
<FormInput
|
||||
key={index}
|
||||
itemParent={item}
|
||||
index={index}
|
||||
onChangeParent={onFeatureFlagsChange}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="center">
|
||||
<button
|
||||
className="settingsSectionButton"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Update Flags
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<fieldset id="appSettings">
|
||||
<p className="settingsSectionLabel">Configurations</p>
|
||||
<div className="fieldSetData">
|
||||
{appSettings.map((item: any, index: any) => (
|
||||
<FormInput
|
||||
key={index}
|
||||
itemParent={item}
|
||||
index={index}
|
||||
onChangeParent={onAppSettingsChange}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="center">
|
||||
<button
|
||||
className="settingsSectionButton"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Update Configurations
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<fieldset id="apiKeys">
|
||||
<p className="settingsSectionLabel">API keys</p>
|
||||
<div className="fieldSetData">
|
||||
{apiKeys.map((item: any, index: any) => (
|
||||
<FormInput
|
||||
key={index}
|
||||
itemParent={item}
|
||||
index={index}
|
||||
onChangeParent={onApiKeysChange}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="container">
|
||||
<div className="center">
|
||||
<button
|
||||
className="settingsSectionButton"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
Update API keys
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Lumino Widget that wraps a GamestonkTerminalSettingsComponent.
|
||||
*
|
||||
* @class TerminalSettingsWidget (name)
|
||||
*/
|
||||
export class TerminalSettingsWidget extends ReactWidget {
|
||||
/**
|
||||
* Constructs a new TerminalSettingsWidget.
|
||||
*/
|
||||
s: ISettingRegistry.ISettings;
|
||||
constructor(s: ISettingRegistry.ISettings) {
|
||||
super();
|
||||
this.addClass("gamestonkSettingsWidget");
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
return <GamestonkTerminalSettingsComponent s={this.s} />;
|
||||
}
|
||||
}
|
||||
99
jupyterlab/openbb-settings/style/base.css
vendored
99
jupyterlab/openbb-settings/style/base.css
vendored
@@ -1,99 +0,0 @@
|
||||
.gamestonkSettingsWidget {
|
||||
color: var(--jp-ui-font-color1);
|
||||
background: var(--jp-layout-color1);
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: left;
|
||||
justify-content: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.gamestonkSettings {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
display: inline;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.settingsForm {
|
||||
min-width: 542px;
|
||||
min-width: 542px;
|
||||
width: 85%;
|
||||
height: 100%;
|
||||
padding-top: var(--jp-private-launcher-top-padding);
|
||||
padding-left: var(--jp-private-launcher-side-padding);
|
||||
padding-right: var(--jp-private-launcher-side-padding);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.inputFieldLabel {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
form fieldset {
|
||||
padding: 6%;
|
||||
border: 1px solid var(--jp-border-color2);
|
||||
}
|
||||
|
||||
form input[type="text" i],
|
||||
form input[type="number" i] {
|
||||
border: 1px solid var(--jp-border-color2);
|
||||
}
|
||||
|
||||
.settingsSectionLabel {
|
||||
font-size: var(--jp-ui-font-size2);
|
||||
font-weight: normal;
|
||||
color: var(--jp-ui-font-color1);
|
||||
margin-bottom: 5%;
|
||||
}
|
||||
|
||||
.settingsSectionButton {
|
||||
display:inline-block;
|
||||
height: 36px;
|
||||
width: 13em;
|
||||
margin:0.1em;
|
||||
padding: 0.2em 1.45em;
|
||||
border:0.05em solid #CCCCCC;
|
||||
box-sizing: border-box;
|
||||
text-decoration:none;
|
||||
font-size: 16px;
|
||||
font-weight: lighter;
|
||||
color:#000000;
|
||||
background-color:#CCCCCC;
|
||||
text-align:center;
|
||||
position:relative;
|
||||
}
|
||||
.settingsSectionButton:hover{
|
||||
border-color:#7a7a7a;
|
||||
}
|
||||
.settingsSectionButton:active{
|
||||
background-color:#999999;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 64px;
|
||||
position: relative;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.settingsSectionUpdateButton {
|
||||
}
|
||||
|
||||
div.fieldSetData {
|
||||
display:grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
grid-gap:5px;
|
||||
}
|
||||
div.fieldSetData label { text-align:right; }
|
||||
div.fieldSetData label:after { content: ":"; }
|
||||
1
jupyterlab/openbb-settings/style/index.css
vendored
1
jupyterlab/openbb-settings/style/index.css
vendored
@@ -1 +0,0 @@
|
||||
@import url('base.css');
|
||||
1
jupyterlab/openbb-settings/style/index.js
vendored
1
jupyterlab/openbb-settings/style/index.js
vendored
@@ -1 +0,0 @@
|
||||
import './base.css';
|
||||
22
jupyterlab/openbb-settings/style/logo.svg
vendored
22
jupyterlab/openbb-settings/style/logo.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 23 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>settings</title>
|
||||
<g id="settings" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="Rectangle" fill="#424242" x="15" y="18" width="225" height="220"></rect>
|
||||
<path d="M116.854147,65.1962028 L125.954036,77.5895858 L128.098262,77.5895858 L137.198151,65.2223492 C139.271789,62.3318774 143.062502,61.2489295 146.350338,62.6077114 L161.019987,68.6475247 C164.3054,69.9974845 166.232064,73.4283204 165.674527,76.9359264 L163.347257,92.1008255 L164.890054,93.6434618 L180.056536,91.3164341 C183.564507,90.7589555 186.995701,92.6854186 188.345802,95.9704894 L194.412395,110.638607 C195.781546,113.925512 194.69663,117.722321 191.797484,119.789839 L179.428957,128.888779 L179.428957,131.032782 L191.797484,140.131721 C194.69663,142.19924 195.781546,145.996049 194.412395,149.282954 L188.345802,163.951071 C186.995701,167.236142 183.564507,169.162605 180.056536,168.605127 L164.890054,166.278099 L163.347257,167.820735 L165.674527,182.985634 C166.232064,186.49324 164.3054,189.924076 161.019987,191.274036 L146.350338,197.339996 C145.417331,197.741826 144.411352,197.946561 143.395489,197.941363 C140.941263,197.943952 138.635386,196.766813 137.198151,194.777651 L128.098262,182.410414 L125.954036,182.410414 L116.854147,194.803797 C114.78051,197.694269 110.989797,198.777217 107.70196,197.418435 L93.0323116,191.274036 C89.7468981,189.924076 87.820234,186.49324 88.3777708,182.985634 L90.7050412,167.820735 L89.162244,166.278099 L73.9957627,168.605127 C70.4877907,169.162605 67.0565969,167.236142 65.7064962,163.951071 L59.6399036,149.282954 C58.2707526,145.996049 59.3556682,142.19924 62.2548142,140.131721 L74.6233412,131.032782 L74.6233412,128.888779 L62.202516,119.789839 C59.30337,117.722321 58.2184544,113.925512 59.5876054,110.638607 L65.7064962,95.9704894 C67.0565969,92.6854186 70.4877907,90.7589555 73.9957627,91.3164341 L89.162244,93.6434618 L90.7050412,92.1008255 L88.3777708,76.9359264 C87.820234,73.4283204 89.7468981,69.9974845 93.0323116,68.6475247 L107.70196,62.581565 C110.989797,61.2227831 114.78051,62.305731 116.854147,65.1962028 Z M146.005273,68.5526316 L136.754354,81.1675213 C135.213998,83.2232711 132.818559,84.4622913 130.250677,84.5314919 L124.92439,84.5314919 C122.295546,84.5251197 119.82745,83.2650372 118.280549,81.1394882 L109.029629,68.5526316 L97.4239309,73.2902235 L99.8067434,88.7364551 C100.207815,91.3618086 99.3452187,94.022347 97.4799971,95.9129257 L93.8076625,99.5852603 C91.936076,101.424973 89.3129567,102.285522 86.7152912,101.912007 L71.1849603,99.5572272 L66.4473684,110.994727 L79.034225,120.245646 C81.159774,121.792548 82.4198565,124.260644 82.4262287,126.889488 L82.4262287,132.35594 C82.4198565,134.984785 81.159774,137.45288 79.034225,138.999782 L66.4473684,148.250701 L71.1849603,159.716235 L86.631192,157.333422 C89.231168,156.932646 91.8662632,157.797124 93.7235633,159.660168 L97.4799971,163.192337 C99.3430411,165.049638 100.207519,167.684733 99.8067434,170.284709 L97.3398317,185.81504 L108.805365,190.552632 L118.056284,177.965775 C119.603186,175.840226 122.071281,174.580143 124.700126,174.573771 L130.250677,174.573771 C132.868127,174.600046 135.324102,175.843578 136.894519,177.937742 L146.145438,190.552632 L157.610971,185.81504 L155.228159,170.368808 C154.783184,167.770558 155.582229,165.113994 157.386707,163.192337 L161.087074,159.520003 C162.958661,157.68029 165.58178,156.819741 168.179446,157.193257 L183.625677,159.576069 L188.363269,148.110536 L175.776413,138.859617 C173.721926,137.324487 172.499172,134.920429 172.468508,132.35594 L172.468508,127.029654 C172.47488,124.400809 173.734963,121.932714 175.860512,120.385812 L188.447368,111.134893 L183.709777,99.5572272 L168.263545,101.912007 C165.638191,102.313078 162.977653,101.450482 161.087074,99.5852603 L157.41474,95.9129257 C155.575027,94.0413392 154.714478,91.4182198 155.087993,88.8205544 L157.470806,73.3743228 L146.005273,68.5526316 Z" id="Combined-Shape" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M127.5,106 C114.521308,106 104,116.521308 104,129.5 C104,142.478692 114.521308,153 127.5,153 C140.478692,153 151,142.478692 151,129.5 C151,123.267412 148.524114,117.290096 144.117009,112.882991 C139.709904,108.475886 133.732588,106 127.5,106 Z" id="Path" stroke="#FFFFFF" stroke-width="10" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB |
24
jupyterlab/openbb-settings/tsconfig.json
vendored
24
jupyterlab/openbb-settings/tsconfig.json
vendored
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"incremental": true,
|
||||
"jsx": "react-jsx",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true,
|
||||
"preserveWatchOutput": true,
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "lib",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"strictNullChecks": false,
|
||||
"target": "es2017",
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/*", "src/**/*"]
|
||||
}
|
||||
91
jupyterlab/openbb-settings/ui-tests/README.md
vendored
91
jupyterlab/openbb-settings/ui-tests/README.md
vendored
@@ -1,91 +0,0 @@
|
||||
# Test
|
||||
|
||||
The test will produce a video to help debugging and check what happened.
|
||||
|
||||
To execute integration tests, you have two options:
|
||||
|
||||
- use docker-compose (cons: needs to know and use docker) - this is a more reliable solution.
|
||||
- run tests locally (cons: will interact with your JupyterLab user settings)
|
||||
|
||||
## Test locally
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Execute in another console the [Playwright](https://playwright.dev/docs/intro) tests:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
npx playwright test
|
||||
```
|
||||
|
||||
# Create tests
|
||||
|
||||
To create tests, the easiest way is to use the code generator tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password:
|
||||
|
||||
|
||||
**Using local installation**
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Launch the code generator tool:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
npx playwright codegen localhost:8888
|
||||
```
|
||||
|
||||
# Debug tests
|
||||
|
||||
To debug tests, a good way is to use the inspector tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
Note: When compiling the extension execute the commands in the extension root (`gst-settings`) folder and not the `gst-settings/ui-tests` folder.
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password:
|
||||
|
||||
**Using local installation**
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Launch the code generator tool:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
PWDEBUG=1 npx playwright test
|
||||
```
|
||||
13
jupyterlab/openbb-settings/ui-tests/package.json
vendored
13
jupyterlab/openbb-settings/ui-tests/package.json
vendored
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "@gamestonk/settings-tests",
|
||||
"version": "0.1.0",
|
||||
"description": "Integration test for the gamestong Settings extension",
|
||||
"repository": "https://github.com/OpenBB-finance/OpenBBTerminal",
|
||||
"author": "OpenBB Terminal Contributors",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.16",
|
||||
"typescript": "~4.1.3"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
timeout: 60000,
|
||||
use: {
|
||||
// Browser options
|
||||
// headless: false,
|
||||
// slowMo: 500,
|
||||
|
||||
// Context options
|
||||
viewport: { width: 1280, height: 720 },
|
||||
|
||||
// Artifacts
|
||||
video: 'on',
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* E2E scenario for testing the Settings menu UI
|
||||
*
|
||||
* Steps:
|
||||
* - Load the extension
|
||||
* - Set a feature flag and save
|
||||
* - Restore settings menu values from user settings
|
||||
* - Unset the feature flag
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const TARGET_URL = process.env.TARGET_URL ?? 'http://localhost:8888';
|
||||
|
||||
test('Test loading of the settings menu', async ({ page }) => {
|
||||
// Open lab
|
||||
await page.goto(`${TARGET_URL}/lab`);
|
||||
await page.waitForSelector('#jupyterlab-splash', { state: 'detached' });
|
||||
await page.waitForSelector('div[role="main"] >> text=Launcher');
|
||||
|
||||
// Click the Settings button in the Launcher panel
|
||||
await page.click('text=settingsSettings >> div');
|
||||
|
||||
// Verify that the extension panel is visible on the same page
|
||||
expect(page.url()).toBe('http://localhost:8888/lab');
|
||||
expect(page.isVisible('#gamestonkSettings')).toBeTruthy();
|
||||
|
||||
// Click the "Clear.after.command" feature flag's checkbox
|
||||
await page.check('#featureFlags > div.fieldSetData > input.Clear.after.command');
|
||||
// Click "Update Flags" text and catch the dialog message
|
||||
page.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`);
|
||||
dialog.dismiss().catch(() => {});
|
||||
});
|
||||
await page.click('text=Update Flags');
|
||||
|
||||
// Check the "Clear.after.command" feature flag's checkbox is checked
|
||||
expect(await page.isChecked('#featureFlags > div.fieldSetData > input.Clear.after.command')).toBeTruthy();
|
||||
|
||||
// Reload the page
|
||||
await page.goto(`${TARGET_URL}/lab`);
|
||||
await page.waitForSelector('#jupyterlab-splash', { state: 'detached' });
|
||||
await page.waitForSelector('div[role="main"] >> text=Launcher');
|
||||
|
||||
// Click the settings button in the Launcher panel
|
||||
await page.click('text=settingsSettings >> div');
|
||||
|
||||
expect(page.url()).toBe('http://localhost:8888/lab');
|
||||
|
||||
// Check the "Clear.after.command" feature flag's checkbox is checked (populated from the user settings)
|
||||
expect(await page.isChecked('#featureFlags > div.fieldSetData > input.Clear.after.command')).toBeTruthy();
|
||||
|
||||
// Uncheck the "Clear.after.command" feature flag's checkbox
|
||||
await page.uncheck('#featureFlags > div.fieldSetData > input.Clear.after.command');
|
||||
// Click "Update Flags" text and catch the dialog message
|
||||
page.once('dialog', dialog => {
|
||||
console.log(`Dialog message: ${dialog.message()}`);
|
||||
dialog.dismiss().catch(() => {});
|
||||
});
|
||||
await page.click('text=Update Flags');
|
||||
|
||||
// Check the "Clear.after.command" feature flag's checkbox is not checked (user settings changed)
|
||||
expect(await page.isChecked('#featureFlags > div.fieldSetData > input.Clear.after.command')).toBeFalsy();
|
||||
|
||||
// Reload the page
|
||||
await page.goto(`${TARGET_URL}/lab`);
|
||||
await page.waitForSelector('#jupyterlab-splash', { state: 'detached' });
|
||||
await page.waitForSelector('div[role="main"] >> text=Launcher');
|
||||
|
||||
// Click the settings button in the Launcher panel
|
||||
await page.click('text=settingsSettings >> div');
|
||||
|
||||
expect(page.url()).toBe('http://localhost:8888/lab');
|
||||
|
||||
// Check the "Clear.after.command" feature flag's checkbox is not checked (populated from the user settings)
|
||||
expect(await page.isChecked('#featureFlags > div.fieldSetData > input.Clear.after.command')).toBeFalsy();
|
||||
|
||||
});
|
||||
1312
jupyterlab/openbb-settings/ui-tests/yarn.lock
vendored
1312
jupyterlab/openbb-settings/ui-tests/yarn.lock
vendored
File diff suppressed because it is too large
Load Diff
6149
jupyterlab/openbb-settings/yarn.lock
vendored
6149
jupyterlab/openbb-settings/yarn.lock
vendored
File diff suppressed because it is too large
Load Diff
5
jupyterlab/openbb/.eslintignore
vendored
5
jupyterlab/openbb/.eslintignore
vendored
@@ -1,5 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
coverage
|
||||
**/*.d.ts
|
||||
ui-tests
|
||||
53
jupyterlab/openbb/.eslintrc.js
vendored
53
jupyterlab/openbb/.eslintrc.js
vendored
@@ -1,53 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/eslint-recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:react/recommended',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'jsdoc'],
|
||||
rules: {
|
||||
'@typescript-eslint/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: 'interface',
|
||||
format: ['PascalCase'],
|
||||
custom: {
|
||||
regex: '^I[A-Z]',
|
||||
match: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }],
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-namespace': 'off',
|
||||
'@typescript-eslint/no-use-before-define': 'off',
|
||||
'@typescript-eslint/quotes': [
|
||||
'error',
|
||||
'double',
|
||||
{ avoidEscape: true, allowTemplateLiterals: false },
|
||||
],
|
||||
curly: ['error', 'all'],
|
||||
eqeqeq: 'error',
|
||||
'jsdoc/require-param-type': 'off',
|
||||
'jsdoc/require-property-type': 'off',
|
||||
'jsdoc/require-returns-type': 'off',
|
||||
'jsdoc/no-types': 'warn',
|
||||
'prefer-arrow-callback': 'error',
|
||||
},
|
||||
settings: {
|
||||
jsdoc: {
|
||||
mode: 'typescript',
|
||||
},
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
};
|
||||
22
jupyterlab/openbb/MANIFEST.in
vendored
22
jupyterlab/openbb/MANIFEST.in
vendored
@@ -1,22 +0,0 @@
|
||||
include LICENSE
|
||||
include README.md
|
||||
include pyproject.toml
|
||||
include jupyter-config/openbb_terminal_launcher.json
|
||||
|
||||
include package.json
|
||||
include ts*.json
|
||||
|
||||
graft openbb_terminal_launcher/labextension
|
||||
|
||||
# Javascript files
|
||||
graft src
|
||||
graft style
|
||||
prune **/node_modules
|
||||
prune lib
|
||||
|
||||
# Patterns to exclude from any directory
|
||||
global-exclude *~
|
||||
global-exclude *.pyc
|
||||
global-exclude *.pyo
|
||||
global-exclude .git
|
||||
global-exclude .ipynb_checkpoints
|
||||
17
jupyterlab/openbb/README.md
vendored
17
jupyterlab/openbb/README.md
vendored
@@ -1,17 +0,0 @@
|
||||
# OpenBB Terminal Launcher
|
||||
|
||||
This extensions adds a button into the OpenBB Terminal category of the Jupyter Lab launcher panel.
|
||||
|
||||
## Install, Use and Develop
|
||||
|
||||
```bash
|
||||
pip install -e .
|
||||
jlpm
|
||||
jlpm run build:prod
|
||||
jupyter labextension install .
|
||||
|
||||
# Rebuild Typescript source after making changes
|
||||
jlpm build
|
||||
# Rebuild JupyterLab after making any changes
|
||||
jupyter lab build
|
||||
```
|
||||
3
jupyterlab/openbb/RELEASE.md
vendored
3
jupyterlab/openbb/RELEASE.md
vendored
@@ -1,3 +0,0 @@
|
||||
# Making a new release of gamestonk-settings
|
||||
|
||||
Check out the [workflow documentation](https://github.com/jupyter-server/jupyter_releaser#typical-workflow) for information.
|
||||
5
jupyterlab/openbb/install.json
vendored
5
jupyterlab/openbb/install.json
vendored
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"packageManager": "python",
|
||||
"packageName": "openbb_terminal_launcher",
|
||||
"uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package openbb_terminal_launcher"
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import json
|
||||
import os.path as osp
|
||||
|
||||
from ._version import __version__ # noqa: F401
|
||||
|
||||
HERE = osp.abspath(osp.dirname(__file__))
|
||||
|
||||
with open(osp.join(HERE, "labextension", "package.json")) as fid:
|
||||
data = json.load(fid)
|
||||
|
||||
|
||||
def _jupyter_labextension_paths():
|
||||
return [{"src": "labextension", "dest": data["name"]}]
|
||||
@@ -1,2 +0,0 @@
|
||||
version_info = (0, 1, 0)
|
||||
__version__ = ".".join(map(str, version_info))
|
||||
95
jupyterlab/openbb/package.json
vendored
95
jupyterlab/openbb/package.json
vendored
@@ -1,95 +0,0 @@
|
||||
{
|
||||
"name": "@gamestonk/terminal",
|
||||
"version": "0.1.0",
|
||||
"description": "Gamestonk terminal launcher",
|
||||
"keywords": [
|
||||
"jupyter",
|
||||
"jupyterlab",
|
||||
"jupyterlab-extension"
|
||||
],
|
||||
"homepage": "https://github.com/OpenBB-finance/OpenBBTerminal",
|
||||
"bugs": {
|
||||
"url": "https://github.com/OpenBB-finance/OpenBBTerminal/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Gamestonk Contributors",
|
||||
"email": "dro.lopes@campus.fct.unl.pt"
|
||||
},
|
||||
"files": [
|
||||
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
|
||||
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}",
|
||||
"style/index.js"
|
||||
],
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"style": "style/index.css",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/OpenBB-finance/OpenBBTerminal.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
|
||||
"build:all": "jlpm run build:lib && jlpm run build:labextension",
|
||||
"build:labextension": "jupyter labextension build .",
|
||||
"build:labextension:dev": "jupyter labextension build --development True .",
|
||||
"build:lib": "tsc",
|
||||
"build:prod": "jlpm run clean && jlpm run build:lib && jlpm run build:labextension",
|
||||
"clean": "jlpm run clean:lib",
|
||||
"clean:all": "jlpm run clean:lib && jlpm run clean:labextension",
|
||||
"clean:labextension": "rimraf openbb_terminal_launcher/labextension",
|
||||
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
|
||||
"eslint": "eslint . --ext .ts,.tsx --fix",
|
||||
"eslint:check": "eslint . --ext .ts,.tsx",
|
||||
"install:extension": "jlpm run build",
|
||||
"prepare": "jlpm run clean && jlpm run build:prod",
|
||||
"watch": "run-p watch:src watch:labextension",
|
||||
"watch:labextension": "jupyter labextension watch .",
|
||||
"watch:src": "tsc -w"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jupyterlab/application": "^3.2.8",
|
||||
"@jupyterlab/apputils": "^3.2.8",
|
||||
"@jupyterlab/filebrowser": "^3.2.8",
|
||||
"@jupyterlab/launcher": "^3.2.8",
|
||||
"@jupyterlab/mainmenu": "^3.2.8",
|
||||
"@jupyterlab/running": "^3.2.8",
|
||||
"@jupyterlab/services": "^6.2.8",
|
||||
"@jupyterlab/settingregistry": "^3.2.8",
|
||||
"@jupyterlab/terminal": "^3.2.8",
|
||||
"@jupyterlab/translation": "^3.2.8",
|
||||
"@jupyterlab/ui-components": "^3.2.8",
|
||||
"@lumino/algorithm": "^1.9.1",
|
||||
"marked": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jupyterlab/builder": "^3.2.8",
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.0",
|
||||
"@typescript-eslint/parser": "^5.10.0",
|
||||
"eslint": "^8.7.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-jsdoc": "^37.6.3",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "<4.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "^0.4.0",
|
||||
"marked": "^4.0.10",
|
||||
"got": "^11.8.5",
|
||||
"jpeg-js": "^0.4.4"
|
||||
},
|
||||
"sideEffects": [
|
||||
"style/*.css",
|
||||
"style/*.svg",
|
||||
"style/index.js"
|
||||
],
|
||||
"jupyterlab": {
|
||||
"extension": true,
|
||||
"outputDir": "openbb_terminal_launcher/labextension"
|
||||
},
|
||||
"styleModule": "style/index.js"
|
||||
}
|
||||
17
jupyterlab/openbb/pyproject.toml
vendored
17
jupyterlab/openbb/pyproject.toml
vendored
@@ -1,17 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.1"]
|
||||
build-backend = "jupyter_packaging.build_api"
|
||||
|
||||
[tool.jupyter-packaging.options]
|
||||
skip-if-exists = ["openbb_terminal_launcher/labextension/static/style.js"]
|
||||
ensured-targets = ["openbb_terminal_launcher/labextension/static/style.js", "openbb_terminal_launcher/labextension/package.json"]
|
||||
|
||||
[tool.jupyter-packaging.builder]
|
||||
factory = "jupyter_packaging.npm_builder"
|
||||
|
||||
[tool.jupyter-packaging.build-args]
|
||||
build_cmd = "build:prod"
|
||||
npm = ["jlpm"]
|
||||
|
||||
[tool.check-manifest]
|
||||
ignore = ["openbb_terminal_launcher/labextension/**", "yarn.lock", ".*", "package-lock.json"]
|
||||
@@ -1,84 +0,0 @@
|
||||
"""
|
||||
openbb_terminal_launcher setup
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import setuptools
|
||||
|
||||
HERE = Path(__file__).parent.resolve()
|
||||
|
||||
# The name of the project
|
||||
name = "openbb_terminal_launcher"
|
||||
|
||||
lab_path = HERE / name.replace("-", "_") / "labextension"
|
||||
|
||||
# Representative files that should exist after a successful build
|
||||
ensured_targets = [str(lab_path / "package.json"), str(lab_path / "static/style.js")]
|
||||
|
||||
labext_name = "@gamestonk/terminal_launcher"
|
||||
|
||||
data_files_spec = [
|
||||
(
|
||||
"share/jupyter/labextensions/%s" % labext_name,
|
||||
str(lab_path.relative_to(HERE)),
|
||||
"**",
|
||||
),
|
||||
("share/jupyter/labextensions/%s" % labext_name, ".", "install.json"),
|
||||
]
|
||||
|
||||
long_description = (HERE / "README.md").read_text()
|
||||
|
||||
# Get the package info from package.json
|
||||
pkg_json = json.loads((HERE / "package.json").read_bytes())
|
||||
|
||||
setup_args = dict(
|
||||
name=name,
|
||||
version=pkg_json["version"],
|
||||
url=pkg_json["homepage"],
|
||||
author=pkg_json["author"]["name"],
|
||||
author_email=pkg_json["author"]["email"],
|
||||
description=pkg_json["description"],
|
||||
license=pkg_json["license"],
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
packages=setuptools.find_packages(),
|
||||
install_requires=[],
|
||||
zip_safe=False,
|
||||
include_package_data=True,
|
||||
python_requires=">=3.6",
|
||||
platforms="Linux, Mac OS X, Windows",
|
||||
keywords=["Jupyter", "JupyterLab", "JupyterLab3"],
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Framework :: Jupyter",
|
||||
],
|
||||
)
|
||||
|
||||
try:
|
||||
from jupyter_packaging import wrap_installers, npm_builder, get_data_files
|
||||
|
||||
post_develop = npm_builder(
|
||||
build_cmd="install:extension", source_dir="src", build_dir=lab_path
|
||||
)
|
||||
setup_args["cmdclass"] = wrap_installers(
|
||||
post_develop=post_develop, ensured_targets=ensured_targets
|
||||
)
|
||||
setup_args["data_files"] = get_data_files(data_files_spec)
|
||||
except ImportError as e:
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format="%(levelname)s: %(message)s")
|
||||
logging.warning(
|
||||
"Build tool `jupyter-packaging` is missing. Install it with pip or conda."
|
||||
)
|
||||
if not ("--name" in sys.argv or "--version" in sys.argv):
|
||||
raise e
|
||||
|
||||
if __name__ == "__main__":
|
||||
setuptools.setup(**setup_args)
|
||||
170
jupyterlab/openbb/src/index.ts
vendored
170
jupyterlab/openbb/src/index.ts
vendored
@@ -1,170 +0,0 @@
|
||||
import {
|
||||
JupyterFrontEnd,
|
||||
JupyterFrontEndPlugin,
|
||||
} from "@jupyterlab/application";
|
||||
|
||||
import { ICommandPalette } from "@jupyterlab/apputils";
|
||||
|
||||
import { ILauncher } from "@jupyterlab/launcher";
|
||||
import { IMainMenu } from "@jupyterlab/mainmenu";
|
||||
import { ISettingRegistry } from "@jupyterlab/settingregistry";
|
||||
|
||||
import { LabIcon } from "@jupyterlab/ui-components";
|
||||
|
||||
import { TerminalManager } from "@jupyterlab/services";
|
||||
import { Terminal } from "@jupyterlab/terminal";
|
||||
|
||||
import appStr from "../style/terminal.svg";
|
||||
|
||||
import { ITerminalSettingsInterface } from "./interfaces";
|
||||
|
||||
const CATEGORY = "OpenBB Terminal";
|
||||
|
||||
/**
|
||||
* The command IDs used by the OpenBB Terminal Launcher plugin.
|
||||
*/
|
||||
namespace CommandIDs {
|
||||
export const create = "gamestonk:terminal";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the section settings values.
|
||||
*
|
||||
* The section settings are taken from the user space (`s.user` if section keys
|
||||
* exist there) or from the default values of the settings schema.
|
||||
*
|
||||
* @param section.section
|
||||
* @param section The section name
|
||||
* @param section.s
|
||||
* @returns The state of the section settings.
|
||||
*/
|
||||
function getSettingsAsArray({ s }: { s: any }): any {
|
||||
const values: Array<Record<string, unknown>> = [];
|
||||
for (const section of ["APP_SETTINGS", "FEATURE_FLAGS", "API_KEYS"]) {
|
||||
Object.keys(s.schema.properties[section].default).forEach(
|
||||
(element: string) => {
|
||||
const settingsValue =
|
||||
typeof s.user[section] === "undefined"
|
||||
? s.schema.properties[section].default[element]
|
||||
: s.user[section][element];
|
||||
values.push({
|
||||
key: element,
|
||||
value: settingsValue,
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization data for the OpenBB Terminal Launcher extension.
|
||||
*/
|
||||
const extension: JupyterFrontEndPlugin<void> = {
|
||||
id: "gamestonk:terminal",
|
||||
autoStart: true,
|
||||
optional: [ILauncher, IMainMenu, ICommandPalette, ISettingRegistry],
|
||||
activate: async (
|
||||
app: JupyterFrontEnd,
|
||||
launcher: ILauncher | null,
|
||||
menu: IMainMenu | null,
|
||||
palette: ICommandPalette | null,
|
||||
settings: ISettingRegistry
|
||||
) => {
|
||||
const { commands } = app;
|
||||
|
||||
const command = CommandIDs.create;
|
||||
const icon = new LabIcon({
|
||||
name: "gamestonk:terminal",
|
||||
svgstr: appStr,
|
||||
});
|
||||
|
||||
const s = await settings.load("@gamestonk/settings:settings");
|
||||
|
||||
commands.addCommand(command, {
|
||||
label: (args) =>
|
||||
args["isPalette"] ? "New OpenBB Terminal" : "OpenBB Terminal",
|
||||
caption: "New OpenBB Terminal",
|
||||
icon: (args) => (args["isPalette"] ? null : icon),
|
||||
execute: async () => {
|
||||
const appSettings = getSettingsAsArray({ s: s });
|
||||
let settingsAsBashVariablesString = "";
|
||||
|
||||
for (const appSetting of appSettings) {
|
||||
settingsAsBashVariablesString = `${settingsAsBashVariablesString} && export ${
|
||||
appSetting.key
|
||||
}=${
|
||||
appSetting.value.value === ""
|
||||
? appSetting.value.default
|
||||
: appSetting.value.value
|
||||
}`;
|
||||
}
|
||||
|
||||
const manager = new TerminalManager();
|
||||
const session = await manager.startNew();
|
||||
const terminal = new Terminal(session, { theme: "dark" });
|
||||
terminal.title.closable = true;
|
||||
|
||||
session.send({
|
||||
type: "stdin",
|
||||
content: ["clear\n"],
|
||||
});
|
||||
|
||||
await new Promise((f) => setTimeout(f, 1000));
|
||||
|
||||
session.send({
|
||||
type: "stdin",
|
||||
content: [`clear${settingsAsBashVariablesString}\nclear\n`],
|
||||
});
|
||||
|
||||
const pythonBinarySetting: ITerminalSettingsInterface = appSettings.find(
|
||||
(i: ITerminalSettingsInterface) => i.key === "PYTHON_BINARY"
|
||||
);
|
||||
const terminalPath: ITerminalSettingsInterface = appSettings.find(
|
||||
(i: ITerminalSettingsInterface) => i.key === "TERMINAL_PATH"
|
||||
);
|
||||
|
||||
const launchCommand = `${
|
||||
pythonBinarySetting.value.value === ""
|
||||
? pythonBinarySetting.value.default
|
||||
: pythonBinarySetting.value.value
|
||||
} ${
|
||||
terminalPath.value.value === ""
|
||||
? terminalPath.value.default
|
||||
: terminalPath.value.value
|
||||
}\n`;
|
||||
|
||||
session.send({
|
||||
type: "stdin",
|
||||
content: [launchCommand],
|
||||
});
|
||||
return terminal;
|
||||
},
|
||||
});
|
||||
|
||||
if (launcher) {
|
||||
launcher.add({
|
||||
command,
|
||||
category: CATEGORY,
|
||||
rank: 2,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the palette
|
||||
if (palette) {
|
||||
palette.addItem({
|
||||
command,
|
||||
args: { isPalette: true },
|
||||
category: CATEGORY,
|
||||
});
|
||||
}
|
||||
|
||||
// Add the command to the menu
|
||||
if (menu) {
|
||||
menu.fileMenu.newMenu.addGroup([{ command }], 30);
|
||||
}
|
||||
console.log("Added OpenBB Terminal Launcher Exstension.");
|
||||
},
|
||||
};
|
||||
|
||||
export default extension;
|
||||
13
jupyterlab/openbb/src/interfaces.ts
vendored
13
jupyterlab/openbb/src/interfaces.ts
vendored
@@ -1,13 +0,0 @@
|
||||
interface ITerminalSettingsObject {
|
||||
default?: string | number;
|
||||
description?: string;
|
||||
form?: string;
|
||||
title?: string;
|
||||
type?: string;
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export interface ITerminalSettingsInterface {
|
||||
key: string;
|
||||
value: ITerminalSettingsObject;
|
||||
}
|
||||
4
jupyterlab/openbb/src/svg.d.ts
vendored
4
jupyterlab/openbb/src/svg.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
declare module '*.svg' {
|
||||
const value: string;
|
||||
export default value;
|
||||
}
|
||||
16
jupyterlab/openbb/style/base.css
vendored
16
jupyterlab/openbb/style/base.css
vendored
@@ -1,16 +0,0 @@
|
||||
.jp-example-view {
|
||||
background-color: AliceBlue;
|
||||
}
|
||||
|
||||
.jp-example-button {
|
||||
background-color: red;
|
||||
border-radius: 12px;
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 15px 32px;
|
||||
margin: 30px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
}
|
||||
1
jupyterlab/openbb/style/index.css
vendored
1
jupyterlab/openbb/style/index.css
vendored
@@ -1 +0,0 @@
|
||||
@import url('base.css');
|
||||
1
jupyterlab/openbb/style/index.js
vendored
1
jupyterlab/openbb/style/index.js
vendored
@@ -1 +0,0 @@
|
||||
import './base.css';
|
||||
22
jupyterlab/openbb/style/logo.svg
vendored
22
jupyterlab/openbb/style/logo.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 23 KiB |
22
jupyterlab/openbb/style/terminal.svg
vendored
22
jupyterlab/openbb/style/terminal.svg
vendored
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 23 KiB |
24
jupyterlab/openbb/tsconfig.json
vendored
24
jupyterlab/openbb/tsconfig.json
vendored
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"esModuleInterop": true,
|
||||
"incremental": true,
|
||||
"jsx": "react",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmitOnError": true,
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": true,
|
||||
"preserveWatchOutput": true,
|
||||
"resolveJsonModule": true,
|
||||
"outDir": "lib",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"strictNullChecks": false,
|
||||
"target": "es2017",
|
||||
"types": []
|
||||
},
|
||||
"include": ["src/*"]
|
||||
}
|
||||
92
jupyterlab/openbb/ui-tests/README.md
vendored
92
jupyterlab/openbb/ui-tests/README.md
vendored
@@ -1,92 +0,0 @@
|
||||
# Test
|
||||
|
||||
The test will produce a video to help debugging and check what happened.
|
||||
|
||||
To execute integration tests, you have two options:
|
||||
|
||||
- use docker-compose (cons: needs to know and use docker) - this is a more reliable solution.
|
||||
- run tests locally (cons: will interact with your JupyterLab user settings)
|
||||
|
||||
## Test locally
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Execute in another console the [Playwright](https://playwright.dev/docs/intro) tests:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
npx playwright test
|
||||
```
|
||||
|
||||
# Create tests
|
||||
|
||||
To create tests, the easiest way is to use the code generator tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password:
|
||||
|
||||
|
||||
**Using local installation**
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Launch the code generator tool:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
npx playwright codegen localhost:8888
|
||||
```
|
||||
|
||||
# Debug tests
|
||||
|
||||
To debug tests, a good way is to use the inspector tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```
|
||||
jlpm install
|
||||
jlpm run build:prod
|
||||
```
|
||||
|
||||
Note: When compiling the extension execute the commands in the extension root (`gst`) folder and not the `gst/ui-tests` folder.
|
||||
|
||||
2. Start JupyterLab _with the extension installed_ without any token or password:
|
||||
|
||||
|
||||
**Using local installation**
|
||||
|
||||
```
|
||||
jupyter lab --ServerApp.token= --ServerApp.password=
|
||||
```
|
||||
|
||||
3. Launch the code generator tool:
|
||||
|
||||
```
|
||||
cd ui-tests
|
||||
jlpm install
|
||||
npx playwright install
|
||||
PWDEBUG=1 npx playwright test --headed
|
||||
```
|
||||
13
jupyterlab/openbb/ui-tests/package.json
vendored
13
jupyterlab/openbb/ui-tests/package.json
vendored
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"name": "@gamestonk/launcher-tests",
|
||||
"version": "0.1.0",
|
||||
"description": "Integration test for terminal launcher",
|
||||
"repository": "https://github.com/OpenBB-finance/OpenBBTerminal",
|
||||
"author": "OpenBB Terminal Contributors",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.16",
|
||||
"typescript": "~4.1.3"
|
||||
}
|
||||
}
|
||||
18
jupyterlab/openbb/ui-tests/playwright.config.ts
vendored
18
jupyterlab/openbb/ui-tests/playwright.config.ts
vendored
@@ -1,18 +0,0 @@
|
||||
import { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
const config: PlaywrightTestConfig = {
|
||||
timeout: 60000,
|
||||
use: {
|
||||
// Browser options
|
||||
// headless: false,
|
||||
// slowMo: 500,
|
||||
|
||||
// Context options
|
||||
viewport: { width: 1280, height: 720 },
|
||||
|
||||
// Artifacts
|
||||
video: 'on',
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Simple scenario placeholder for testing the Gamestonk Launcher
|
||||
*
|
||||
* Steps:
|
||||
* - Wait for the launcher panel to load
|
||||
* - Launch the terminal
|
||||
* - Wait for the terminal to initialize
|
||||
* - Press "return" three times
|
||||
*
|
||||
* This is a placeholder for the test.
|
||||
* Depending on the future testing/QA decisions this test can be expanded.
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
const TARGET_URL = process.env.TARGET_URL ?? 'http://localhost:8888';
|
||||
|
||||
test('Should open a panel with the OpenBBTerminal and send "Enter" three times', async ({ page }) => {
|
||||
await page.goto(`${TARGET_URL}/lab`);
|
||||
await page.waitForSelector('#jupyterlab-splash', { state: 'detached' });
|
||||
await page.waitForSelector('div[role="main"] >> text=Launcher');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(/*{ url: 'http://localhost:8888/lab' }*/),
|
||||
page.click('p:has-text("OpenBB Terminal")')
|
||||
]);
|
||||
|
||||
expect(
|
||||
await page.waitForSelector('[aria-label="Terminal input"]', { timeout: 1000 })
|
||||
).toBeTruthy();
|
||||
|
||||
// Press Enter a couple of times
|
||||
await page.waitForTimeout(3000)
|
||||
await page.press('[aria-label="Terminal input"]', 'Enter');
|
||||
await page.press('[aria-label="Terminal input"]', 'Enter');
|
||||
await page.press('[aria-label="Terminal input"]', 'Enter');
|
||||
await page.waitForTimeout(1000)
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user