[Feature] Open Data Platform Desktop Application (#7238)

* add desktop app code to repository

* fix headers

* bump version

* one more file to bump version in

* cargo fmt

* add permissions to release jobs

* codespell

* Need this folder to exist

* NSNumber apparently

* cargo fmt

* test expectation that didn't get updated

* intel mac runner is macos-15-intel

* empty line at bottom of file..

* apparently didn't save permissions step

* unused windows import

* cargo fmt again

* draft-release workflow

* fix windows test

* try as reusable workflow

* beforeBundleCommand

* relative path

* absolute path...

* the file definitely exists...

* seems that the file was not actually added....

* this file definitely exists

* undo temp edit of draft-release
This commit is contained in:
Danglewood
2025-10-14 08:52:04 -07:00
committed by GitHub
parent 9e3cb50bf6
commit 039c183c60
178 changed files with 114251 additions and 5726 deletions

7
.codespell.skip vendored
View File

@@ -13,6 +13,7 @@
*.scss
*.txt
*.yaml
*.cdx.xml
./build/pyinstaller
./**/node_modules
./frontend-components/**
@@ -20,4 +21,8 @@
./openbb_platform/core/openbb/package/**
./openbb_platform/providers/imf/openbb_imf/utils/constants.py
./openbb_platform/extensions/economy/openbb_economy/economy_views.py
./openbb_platform/providers/fmp/openbb_fmp/models/calendar_ipo.py
./openbb_platform/providers/fmp/openbb_fmp/models/calendar_ipo.py
./desktop/src-tauri/src/tauri_handlers/startup.rs
./desktop/src/routes/environments.tsx
./desktop/src/tests/routes/installation-progress.test.tsx
./desktop/src/tests/routes/index.test.tsx

View File

@@ -0,0 +1,112 @@
name: build-macos-x64
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: "macos-15-intel"
permissions:
contents: write
defaults:
run:
working-directory: desktop
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Import Code Signing Certificate
uses: apple-actions/import-codesign-certs@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
with:
p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }}
p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
- name: Install OpenSSL
run: brew install openssl
- name: Setup Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-registry-
- name: Setup Node Cache
uses: actions/cache@v4
with:
path: ~/.npm
key: macos-x64-node-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-x64-node-
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: "x86_64-apple-darwin"
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if [ -f "src-tauri/openbb-platform.cdx.xml" ]; then
mv src-tauri/openbb-platform.cdx.xml "src-tauri/open-data-platform-SBOM-cargo.cdx.xml"
fi
- name: Build Tauri App
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.NOTARIZE_APPLE_PWD }}
APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: npm run tauri build
- name: Rename artifacts
run: |
VERSION=$(jq -r .version src-tauri/tauri.conf.json)
cd target/release/bundle/dmg
for file in *.dmg; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.dmg"; done
cd ../macos
for file in *.app.tar.gz; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.app.tar.gz"; done
for file in *.app.tar.gz.sig; do mv "$file" "Open-Data-Platform_${VERSION}_x86_64.app.tar.gz.sig"; done
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: macos-x64-artifacts
path: |
desktop/target/release/bundle/dmg/*.dmg
desktop/target/release/bundle/macos/*.app.tar.gz
desktop/target/release/bundle/macos/*.app.tar.gz.sig
- name: Cleanup Artifacts
if: always()
run: cargo clean

View File

@@ -0,0 +1,127 @@
name: build-macos-arm
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: "macos-latest"
permissions:
contents: write
defaults:
run:
working-directory: desktop
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Debug - List files
run: |
echo "Current directory:"
pwd
echo "Files in current directory:"
ls -la
echo "Files in src-tauri:"
ls -la src-tauri/
echo "Files in src-tauri/scripts:"
ls -la src-tauri/scripts/ || echo "scripts directory does not exist"
echo "Looking for fix_dylibs.sh:"
find . -name "fix_dylibs.sh" -type f || echo "fix_dylibs.sh not found"
- name: Import Code Signing Certificate
uses: apple-actions/import-codesign-certs@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
with:
p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }}
p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }}
- name: Install OpenSSL
run: brew install openssl
- name: Setup Cargo Cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-arm-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm-cargo-registry-
- name: Setup Node Cache
uses: actions/cache@v4
with:
path: ~/.npm
key: macos-arm-node-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-arm-node-
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: install Rust stable
uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
targets: "aarch64-apple-darwin"
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if [ -f "src-tauri/openbb-platform.cdx.xml" ]; then
mv src-tauri/openbb-platform.cdx.xml "src-tauri/open-data-platform-SBOM-cargo.cdx.xml"
fi
- name: Build Tauri App
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
APPLE_ID: ${{ secrets.NOTARIZE_APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.NOTARIZE_APPLE_PWD }}
APPLE_TEAM_ID: ${{ secrets.NOTARIZE_APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: npm run tauri build
- name: Rename artifacts
run: |
VERSION=$(jq -r .version src-tauri/tauri.conf.json)
cd target/release/bundle/dmg
for file in *.dmg; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.dmg"; done
cd ../macos
for file in *.app.tar.gz; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.app.tar.gz"; done
for file in *.app.tar.gz.sig; do mv "$file" "Open-Data-Platform_${VERSION}_aarch64.app.tar.gz.sig"; done
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: macos-arm-artifacts
path: |
desktop/target/release/bundle/dmg/*.dmg
desktop/target/release/bundle/macos/*.app.tar.gz
desktop/target/release/bundle/macos/*.app.tar.gz.sig
- name: Cleanup Artifacts
if: always()
run: cargo clean

View File

@@ -0,0 +1,175 @@
name: build-windows-x64
on:
workflow_call:
inputs:
release:
required: false
type: boolean
default: false
jobs:
build-and-sign:
runs-on: windows-latest
permissions:
contents: write
defaults:
run:
working-directory: desktop
env:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
steps:
- uses: actions/checkout@v4
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}
key: ${{ runner.os }}-vcpkg-${{ hashFiles('desktop/**/vcpkg.json') }}
restore-keys: |
${{ runner.os }}-vcpkg-
- name: Bootstrap vcpkg
working-directory: ${{ github.workspace }}
run: |
if (-not (Test-Path ${{ env.VCPKG_ROOT }})) {
git clone https://github.com/microsoft/vcpkg.git ${{ env.VCPKG_ROOT }}
}
${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.bat
shell: pwsh
- name: Install OpenSSL using vcpkg
working-directory: ${{ github.workspace }}
run: ${{ env.VCPKG_ROOT }}/vcpkg install openssl:x64-windows-static --vcpkg-root ${{ env.VCPKG_ROOT }}
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
- name: Set OpenSSL env
shell: bash
run: |
echo "OPENSSL_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static" >> $GITHUB_ENV
echo "OPENSSL_INCLUDE_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/include" >> $GITHUB_ENV
echo "OPENSSL_LIB_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/lib" >> $GITHUB_ENV
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install cyclonedx-npm
run: npm install -g @cyclonedx/cyclonedx-npm
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: windows-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: windows-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-build-
- name: Install Modules
run: |
npm install
cyclonedx-npm --output-format XML --gather-license-texts --output-file src-tauri/open-data-platform-SBOM-npm.cdx.xml
- name: Install cargo-cyclonedx
shell: pwsh
run: |
cargo install cargo-cyclonedx
cargo cyclonedx
if (Test-Path "src-tauri/openbb-platform.cdx.xml") {
Move-Item "src-tauri/openbb-platform.cdx.xml" "src-tauri/open-data-platform-SBOM-cargo.cdx.xml" -Force
}
- name: Build Tauri App (without bundling)
run: npm run tauri build -- --target x86_64-pc-windows-msvc --no-bundle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create backup of unsigned executable
shell: pwsh
run: |
Copy-Item -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe" -Destination "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform-unsigned.exe"
- name: Create temp directory for signing
shell: pwsh
run: New-Item -ItemType Directory -Force -Path "${{ github.workspace }}/desktop/temp-sign"
- name: Sign the executable
uses: sslcom/esigner-codesign@v1.3.1
with:
command: sign
username: ${{ secrets.ESIGNER_USERNAME }}
password: ${{ secrets.ESIGNER_PASSWORD }}
credential_id: ${{ secrets.ESIGNER_CREDENTIAL_ID }}
totp_secret: ${{ secrets.ESIGNER_TOTP_SECRET }}
file_path: ${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe
output_path: ${{ github.workspace }}/desktop/temp-sign
malware_block: false
- name: Replace unsigned executable with signed one
shell: pwsh
run: |
Copy-Item -Path "${{ github.workspace }}/desktop/temp-sign/openbb-platform.exe" -Destination "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/openbb-platform.exe" -Force
- name: Bundle the signed executable into installer
run: npm run tauri bundle -- --target x86_64-pc-windows-msvc --bundles nsis
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
- name: Get Installer Path
id: get_installer_path
shell: pwsh
run: |
$installerPath = (Get-ChildItem -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe").FullName
echo "installer_path=$installerPath" >> $env:GITHUB_OUTPUT
- name: Create directory for signed installer
shell: pwsh
run: New-Item -ItemType Directory -Force -Path "${{ github.workspace }}/desktop/signed-installer"
- name: Sign Installer
uses: sslcom/esigner-codesign@v1.3.1
with:
command: sign
username: ${{ secrets.ESIGNER_USERNAME }}
password: ${{ secrets.ESIGNER_PASSWORD }}
credential_id: ${{ secrets.ESIGNER_CREDENTIAL_ID }}
totp_secret: ${{ secrets.ESIGNER_TOTP_SECRET }}
file_path: ${{ steps.get_installer_path.outputs.installer_path }}
output_path: ${{ github.workspace }}/desktop/signed-installer
malware_block: true
- name: Organize artifacts
shell: pwsh
run: |
$version = (Get-Content src-tauri/tauri.conf.json | ConvertFrom-Json).version
$sigFile = (Get-ChildItem -Path "${{ github.workspace }}/desktop/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.sig").FullName
Copy-Item -Path $sigFile -Destination "${{ github.workspace }}/desktop/signed-installer/"
cd ${{ github.workspace }}/desktop/signed-installer
Get-ChildItem -Path "*.exe" | Rename-Item -NewName "Open-Data-Platform_${version}_x86_64.exe"
Get-ChildItem -Path "*.sig" | Rename-Item -NewName "Open-Data-Platform_${version}_x86_64.exe.sig"
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: windows-x64-artifacts
path: ${{ github.workspace }}/desktop/signed-installer/

View File

@@ -1,222 +0,0 @@
name: MacOS Build
env:
OPENBB_LOG_COLLECT: false
OPENBB_USE_PROMPT_TOOLKIT: false
OPENBB_FILE_OVERWRITE: true
PIP_DEFAULT_TIMEOUT: 100
PYTHONNOUSERSITE: 1
on: workflow_dispatch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
M1-MacOs-Build:
name: M1 MacOS Build
runs-on: [self-hosted, macos, ARM64]
permissions:
contents: read
steps:
# Checkout repository main branch. this allows for the commit hashes to line up
- name: Checkout
uses: actions/checkout@v3
- name: Git Log
run: git log
# The following commands to clear previous PATHS and restore to defaults since we have to maintain the instance ourselves
- name: Clean Previous Path
run: |
export PATH=""
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
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@v3
with:
path: ~/conda_pkgs_dir
key: conda-macos-3-10-${{ hashFiles('build/conda/environments/constructor.yml') }}
# Set up miniconda using the environment yaml file within the repo
- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3.0.4
with:
miniconda-version: "latest"
auto-update-conda: true
channels: conda-forge,defaults
show-channel-urls: true
channel-priority: flexible
environment-file: build/conda/environments/constructor.yml
activate-environment: constructor
auto-activate-base: false
- name: Creating Application 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: Create Signed Package
env:
MACOS_INSTALLER_KEYCHAIN_PWD: ${{ secrets.MACOS_INSTALLER_KEYCHAIN_PWD }}
MACOS_INSTALLER_SIGNING_IDENTITY_NAME: ${{ secrets.MACOS_CODESIGN_INSTALLER_IDENTITY_NAME }}
MACOS_APPLICATION_SIGNING_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
security unlock-keychain -p $MACOS_INSTALLER_KEYCHAIN_PWD install.keychain
echo "signing_identity_name: $MACOS_INSTALLER_SIGNING_IDENTITY_NAME" >> build/conda/installer/construct.yaml
echo "notarization_identity_name: $MACOS_APPLICATION_SIGNING_IDENTITY" >> build/conda/installer/construct.yaml
cd build/conda && constructor installer/. && cd ../../
mv build/conda/OpenBB-Platform-MacOSX-arm64.pkg OpenBB-Platform-MacOSX-arm64.pkg
shell: bash -l {0}
- 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/conda/tmp
- name: Notarize 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-Platform-MacOSX-arm64.pkg --apple-id "$NOTARIZE_APPLE_ID" --password "$NOTARIZE_APPLE_PWD" --team-id "$NOTARIZE_APPLE_TEAM_ID" --wait
- name: Staple
run: |
xcrun stapler staple OpenBB-Platform-MacOSX-arm64.pkg
- name: Save Build Artifact PKG
uses: actions/upload-artifact@v4
with:
name: OpenBBM1.pkg
path: OpenBB-Platform-MacOSX-arm64.pkg
- name: Clean up Build Artifacts
run: |
rm OpenBB-Platform-MacOSX-arm64.pkg
# Job to build the MacOS Intel version of the Terminal===================================
Intel-MacOs-Build:
name: Intel MacOS Build
runs-on: [self-hosted, macos, x64]
permissions:
contents: read
steps:
# Checkout repository main branch. this allows for the commit hashes to line up
- name: Checkout
uses: actions/checkout@v3
- name: Git Log
run: git log
# The following commands to clear previous PATHS and restore to defaults since we have to maintain the instance ourselves
- name: Clean Previous Path
run: |
export PATH=""
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
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@v3
with:
path: ~/conda_pkgs_dir
key: conda-macos-3-10-${{ hashFiles('build/conda/environments/constructor.yml') }}
# Set up miniconda using the environment yaml file within the repo
- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3.0.4
with:
miniconda-version: "latest"
auto-update-conda: true
channels: conda-forge,defaults
show-channel-urls: true
channel-priority: flexible
environment-file: build/conda/environments/constructor.yml
activate-environment: constructor
auto-activate-base: false
- name: Creating Application 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: Create Signed Package
env:
MACOS_INSTALLER_KEYCHAIN_PWD: ${{ secrets.MACOS_INSTALLER_KEYCHAIN_PWD }}
MACOS_INSTALLER_SIGNING_IDENTITY_NAME: ${{ secrets.MACOS_CODESIGN_INSTALLER_IDENTITY_NAME }}
MACOS_APPLICATION_SIGNING_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
security unlock-keychain -p $MACOS_INSTALLER_KEYCHAIN_PWD install.keychain
echo "signing_identity_name: $MACOS_INSTALLER_SIGNING_IDENTITY_NAME" >> build/conda/installer/construct.yaml
echo "notarization_identity_name: $MACOS_APPLICATION_SIGNING_IDENTITY" >> build/conda/installer/construct.yaml
cd build/conda && constructor installer/. && cd ../../
mv build/conda/OpenBB-Platform-MacOSX-x86_64.pkg OpenBB-Platform-MacOSX-x86_64.pkg
shell: bash -l {0}
- 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/conda/tmp
- name: Notarize 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-Platform-MacOSX-x86_64.pkg --apple-id "$NOTARIZE_APPLE_ID" --password "$NOTARIZE_APPLE_PWD" --team-id "$NOTARIZE_APPLE_TEAM_ID" --wait
- name: Staple
run: |
xcrun stapler staple OpenBB-Platform-MacOSX-x86_64.pkg
- name: Save Build Artifact PKG
uses: actions/upload-artifact@v4
with:
name: OpenBBIntel.pkg
path: OpenBB-Platform-MacOSX-x86_64.pkg
- name: Clean up Build Artifacts
run: |
rm OpenBB-Platform-MacOSX-x86_64.pkg

219
.github/workflows/release-desktop.yml vendored Normal file
View File

@@ -0,0 +1,219 @@
name: Release ODP Desktop
on:
workflow_call:
inputs:
tag:
required: true
type: string
draft:
required: true
type: boolean
release:
types: [published]
workflow_dispatch:
inputs:
tag:
description: "Tag for release"
required: false
default: ""
draft:
description: "Create as draft release"
required: false
default: "false"
jobs:
build-windows:
uses: ./.github/workflows/build-desktop-win64.yml
with:
release: true
secrets: inherit
permissions:
contents: write
build-macos-arm:
uses: ./.github/workflows/build-desktop-osxARM.yml
with:
release: true
secrets: inherit
permissions:
contents: write
build-macos-x64:
uses: ./.github/workflows/build-desktop-osx64.yml
with:
release: true
secrets: inherit
permissions:
contents: write
publish:
needs: [build-windows, build-macos-arm, build-macos-x64]
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.extract_version.outputs.version }}
tag: ${{ steps.extract_version.outputs.tag }}
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Sanitize artifact filenames
run: |
find ./artifacts -depth -name "* *" | while read -r file; do mv "$file" "$(echo "$file" | tr ' ' '-')"; done
- name: Extract Version and Tag
id: extract_version
run: |
# Use input tag if provided, otherwise extract from artifacts
if [ -n "${{ github.event.inputs.tag }}" ]; then
TAG="${{ github.event.inputs.tag }}"
VERSION=$(echo "$TAG" | sed 's/^[^0-9]*//')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "release_name=Open Data Platform $TAG" >> $GITHUB_OUTPUT
echo "tag=$TAG" >> $GITHUB_OUTPUT
else
INSTALLER_FILE=$(find ./artifacts -name "*.exe" -o -name "*.dmg" | head -n 1)
if [ -z "$INSTALLER_FILE" ]; then
echo "::error::No installer file found in artifacts."
exit 1
fi
VERSION=$(basename "$INSTALLER_FILE" | sed -n 's/.*_\([0-9]\+\.[0-9]\+\.[0-9]\+\)_.*/\1/p')
if [ -z "$VERSION" ]; then
echo "::error::Could not extract version from filename: $(basename "$INSTALLER_FILE")"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "release_name=Open Data Platform v$VERSION" >> $GITHUB_OUTPUT
echo "tag=Open-Data-Platform-v$VERSION" >> $GITHUB_OUTPUT
fi
- name: Prepare assets and generate release.json
id: prep_assets
run: |
mkdir ./release_assets
find ./artifacts -type f -print -exec cp {} ./release_assets/ \;
cd ./release_assets
VERSION="${{ steps.extract_version.outputs.version }}"
RELEASE_NAME="${{ steps.extract_version.outputs.release_name }}"
TAG="${{ steps.extract_version.outputs.tag }}"
cat << EOF > release.json
{
"version": "$VERSION",
"notes": "Release for $RELEASE_NAME",
"pub_date": "$(date -u +'%Y-%m-%dT%H:%M:%SZ')",
"platforms": {
EOF
WIN_EXE=$(find . -name "*_x86_64.exe" | head -n 1)
if [ -n "$WIN_EXE" ]; then
WIN_SIG_FILE="${WIN_EXE}.sig"
WIN_SIG=$(cat "$WIN_SIG_FILE")
WIN_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$WIN_EXE")"
cat << EOF >> release.json
"windows-x86_64": {
"signature": "$WIN_SIG",
"url": "$WIN_URL"
}
EOF
fi
MAC_ARM_TAR=$(find . -name "*_aarch64.app.tar.gz" | head -n 1)
if [ -n "$MAC_ARM_TAR" ]; then
if [ -n "$WIN_EXE" ]; then
echo "," >> release.json
fi
MAC_ARM_SIG=$(cat "${MAC_ARM_TAR}.sig")
MAC_ARM_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$MAC_ARM_TAR")"
cat << EOF >> release.json
"darwin-aarch64": {
"signature": "$MAC_ARM_SIG",
"url": "$MAC_ARM_URL"
}
EOF
fi
MAC_X64_TAR=$(find . -name "*_x86_64.app.tar.gz" | head -n 1)
if [ -n "$MAC_X64_TAR" ]; then
if [ -n "$WIN_EXE" ] || [ -n "$MAC_ARM_TAR" ]; then
echo "," >> release.json
fi
MAC_X64_SIG=$(cat "${MAC_X64_TAR}.sig")
MAC_X64_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/$(basename "$MAC_X64_TAR")"
cat << EOF >> release.json
"darwin-x86_64": {
"signature": "$MAC_X64_SIG",
"url": "$MAC_X64_URL"
}
EOF
fi
cat << EOF >> release.json
}
}
EOF
echo "Generated release.json:"
cat release.json
cd ..
echo "assets_path=./release_assets" >> $GITHUB_OUTPUT
- name: Upload release assets
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.extract_version.outputs.tag }}
name: ${{ steps.extract_version.outputs.release_name }}
files: ${{ steps.prep_assets.outputs.assets_path }}/*
draft: ${{ github.event.inputs.draft == 'true' }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload release.json as artifact for odp job
uses: actions/upload-artifact@v4
with:
name: release-json
path: ./release_assets/release.json
update-latest-tag:
needs: publish
# Only run this job if not a draft release
if: github.event.inputs.draft != 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download release artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Delete existing odp tag and release
continue-on-error: true
run: |
gh release delete odp --yes || true
git push origin :refs/tags/odp || true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare latest assets
run: |
mkdir ./odp_assets
find ./artifacts -name "*.exe" -exec cp {} ./odp_assets/ \;
find ./artifacts -name "*.dmg" -exec cp {} ./odp_assets/ \;
if [ -f ./artifacts/release-json/release.json ]; then
cp ./artifacts/release-json/release.json ./odp_assets/latest.json
fi
- name: Create latest release
uses: softprops/action-gh-release@v1
with:
tag_name: odp
name: Latest Release
body: |
This is the latest stable release.
For version-specific details, see the corresponding versioned release.
files: ./odp_assets/*
prerelease: false
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,83 @@
name: Test macOS x64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-macos-x64:
runs-on: macos-15-intel
permissions:
contents: read
defaults:
run:
working-directory: desktop
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: macos-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-x64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: macos-x64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-x64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false

View File

@@ -0,0 +1,86 @@
name: Test macOS ARM64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-macos-arm64:
runs-on: macos-latest
permissions:
contents: read
defaults:
run:
working-directory: desktop
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Add Rust target (macOS ARM only)
run: rustup target add aarch64-apple-darwin
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: macos-arm64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: macos-arm64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
macos-arm64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: macos-arm64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
macos-arm64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false

View File

@@ -0,0 +1,115 @@
name: Test Windows x64
on:
pull_request:
branches:
- develop
paths:
- 'desktop/**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
test-windows-x64:
runs-on: windows-latest
permissions:
contents: read
defaults:
run:
working-directory: desktop
env:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
steps:
- uses: actions/checkout@v4
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: ${{ env.VCPKG_ROOT }}
key: ${{ runner.os }}-vcpkg-${{ hashFiles('desktop/**/vcpkg.json') }}
restore-keys: |
${{ runner.os }}-vcpkg-
- name: Bootstrap vcpkg
working-directory: ${{ github.workspace }}
run: |
if (-not (Test-Path ${{ env.VCPKG_ROOT }})) {
git clone https://github.com/microsoft/vcpkg.git ${{ env.VCPKG_ROOT }}
}
${{ env.VCPKG_ROOT }}/bootstrap-vcpkg.bat
shell: pwsh
- name: Install OpenSSL using vcpkg
working-directory: ${{ github.workspace }}
run: ${{ env.VCPKG_ROOT }}/vcpkg install openssl:x64-windows-static --vcpkg-root ${{ env.VCPKG_ROOT }}
env:
VCPKG_DEFAULT_TRIPLET: x64-windows-static
- name: Set OpenSSL env
shell: bash
run: |
echo "OPENSSL_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static" >> $GITHUB_ENV
echo "OPENSSL_INCLUDE_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/include" >> $GITHUB_ENV
echo "OPENSSL_LIB_DIR=${{ env.VCPKG_ROOT }}/installed/x64-windows-static/lib" >> $GITHUB_ENV
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy, rustfmt
override: true
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: windows-x64-cargo-registry-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-registry-
- name: Cache cargo build
uses: actions/cache@v4
with:
path: desktop/target
key: windows-x64-cargo-build-${{ hashFiles('desktop/**/Cargo.lock') }}
restore-keys: |
windows-x64-cargo-build-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy linter
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run tests
run: cargo test --all
- name: Cache node_modules
uses: actions/cache@v4
with:
path: desktop/node_modules
key: windows-x64-node-modules-${{ hashFiles('desktop/**/package-lock.json') }}
restore-keys: |
windows-x64-node-modules-
- name: Install frontend dependencies
run: npm ci
- name: Lint frontend code
run: npm run lint
- name: Type check
run: ./node_modules/.bin/tsc --noEmit
- name: Run frontend tests
run: npm run test -- --watch=false

2
.gitignore vendored
View File

@@ -48,7 +48,7 @@ build/nsis/app
DMG/*
*.dmg
*.sh
cli/openbb_cli/assets/styles/user/hub.richstyle.json
cli/openbb_cli/assets/styles/user/*
# Platform
openbb_platform/core/openbb/package/*

38
build/conda/README.md vendored
View File

@@ -1,38 +0,0 @@
# OpenBB Platform Installer
The code in this folder creates a packaged installer for the OpenBB Platform, using Conda Constructor.
The installers can be created for Windows (.exe), macOS (.pkg).
The installer is distributed with a Conda environment that contains Python and package management tools.
The dependencies required to run the application are installed from PyPI by the constructor's post_install script. They are installed by poetry and are defined in the `installer/assets/openbb_platform_installer/pyproject.toml` file.
The version of Python is defined in the `construct.yaml` file. It is set for 3.12.
## Build Instructions
**In order to build the installer, conda should be already installed and initialized your current shell profile.**
Navigate into the `build/conda` folder and then begin.
1. Create the Conda environment.
- `conda env create --file environments/constructor.yml`
2. Activate the environment.
- `conda activate constructor`
3. Build the installer.
- `constructor installer/.`
## For when we have a full NSIS
To check nsis file - run
```batch
miniconda3\envs\constructor\NSIS\makensis.exe /V2 assets\installer.nsi
```
gives better output for errors
```batch
miniconda3\envs\constructor\NSIS\makensis.exe /V4 assets\installer.nsi
```

View File

@@ -1,10 +0,0 @@
name: constructor
channels:
- conda-forge
- defaults
dependencies:
- conda-build
- constructor>=3.9.3
- six
- urllib3
- requests

View File

@@ -1,246 +0,0 @@
# OpenBB Platform
Thanks for installing the OpenBB Platform. To get the most out of your experience, we recommend reviewing the contents of this document.
If you have never used Python before, don't worry, your first time is just a double-click away. The sections below outline everything you need to know for getting started.
## What Did I Install?
This is a kitted out development container for Pythonic, open source, financial research. It has everything you need to get started immediately.
Included is a complete installation of the OpenBB Platform and CLI, along with Conda and Jupyter Notebook, in an isolated Python 3.12 Conda environment.
If you already have an installation of Conda or Anaconda, the version in this folder will not rely on, interfere, or share base environment paths with, existing versions.
Tools for managing, updating, and building environments allow you to take full control of your installation, as well as quickly spin up new containers within this project folder.
Follow the quick start steps below to get started using right away; or, open one of the shortcuts described below.
If you want to build your own endpoints, connections, and features, try installing the [example extensions](#examples)
## OpenBB Workspace Quick Start
- Login to the [OpenBB Hub](https://my.openbb.co)
- Optionally, add API keys for remote authorization on the page [here](https://my.openbb.dev/app/platform/credentials).
- If credentials have been added, from the sidebar, click on 'Personal Access Token'.
- Generate a token and copy the value to the clipboard.
- Optionally, from the sidebar, click on 'Widgets' to filter out any provider extensions or endpoints you wish to exclude.
- Without filtering, there will be well over 300 individual widgets. This will narrow the field and focus on only what you need.
- After configuring, download the file ("widget_settings.json") and save it to, `~/.openbb_platform`. The "Settings" shortcut takes you there.
- Double-click on the `openbb-api` shortcut.
- If you generated a personal access token, paste the values that were copied to the clipboard and hit the return key.
- Enter y/n to persist the downloaded credentials on the local machine for future sessions.
- By default, the server will be running on: [http://127.0.0.1:6900](http://127.0.0.1:6900)
- Login to OpenBB Workspace [here](https://pro.openbb.co)
- From the sidebar, click on, "Data Connectors".
- Then click on the button, "Add Data".
- In the pop-up menu, select "Custom Backend".
- Enter a name for the connection - i.e, "OpenBB Platform"
- Enter the address the server is running on - i.e, "http://127.0.0.1:6900"
- **Ensure that "Validate Widgets" is set to "No".**
- Click on the "Test" button.
- Finally, click on the "Add" button.
The OpenBB Platform API widgets can now be added to any dashboard. For a more detailed version of these instructions, see the documentation page [here](https://docs.openbb.co/pro/custom-backend)
## Shortcuts
At the root of the installation folder (where this document is) are shortcuts for launchers and to key file locations.
- Bash (Windows: CMD): Opens a command line shell with the base Conda environment activated. Activate the OpenBB environment with:
- Mac/Linux: `source activate obb`
- Windows: `conda activate obb`
- Environments: Shortcut to the root "envs" folder, where the `obb` and any created environments are stored.
- "widgets.json" is located in the "assets" subdirectory.
- openbb-api: Opens a Terminal window and launches the OpenBB API, with optional prompts to login with your OpenBB Hub PAT.
- openbb-cli: Opens a Terminal window and launches the OpenBB CLI (formerly OpenBB Terminal).
- openbb-ipython: Opens a Terminal window and starts an IPython session with the OpenBB Platform package imported.
- openbb-notebook: Opens a Terminal window, starts the Jupyter development server, and opens a browser window with the Notebook application.
- OpenBBUserData: Shortcut to the OpenBBUserData folder. Files exported from CLI are saved here.
- Settings: Shortcut to the `~/.openbb_platform` location where `.env` files and `user_settings.json` are stored.
- If you cannot see the ".env" file, set Finder/Explorer to display hidden/system files.
- Update: Opens a Terminal window and updates the OpenBB Platform environment (obb) and packages.
## Command Line Entry Points
There are several command line entry points available when either:
- The OpenBB Platform environment (obb) is active.
- The "openbb_platform_installer" package has been installed in the active Python environment.
### OpenBB Entry Points
- openbb: Launches the OpenBB CLI.
- openbb-api: Launches the API and accepts select arguments.
- All args/kwargs available to `uvicorn run` are exposed.
- `--login`: True/False. Defeats the login prompt when False.
- `--no-build`: Skips building "widgets.json"
- openbb-build: Runs the build script that generates the static assets for the OpenBB Python interface.
- Run this after installing/uninstalling/updating OpenBB extensions
- Automatically run when `openbb-update` is run.
- openbb-update: Updates the environment packages defined in `pyproject.toml` and `poetry.lock` and rebuilds the OpenBB Python interface.
- Location of Poetry files: "/extensions/openbb_platform_installer"
- Passes all args/kwargs to `poetry install`.
### Starting The OpenBB Platform API With Optional Arguments
1. Open the `Bash` (`CMD` on Windows) shortcut.
2. Activate the `obb` environment
- Unix: `source activate obb`
- Windows: `conda activate obb`
3. Run `openbb-api` with `--parameter value` to add any `uvicorn.run` parameter.
### OpenBB Platform API Over HTTPS
To run the API over the HTTPS protocol, you must first create a self-signed certificate and the associated key. After steps 1 & 2 above, you can generate the files by entering this to the command line:
```sh
openssl req -x509 -days 3650 -out localhost.crt -keyout localhost.key -newkey rsa:4096 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
```
Two files will be created, in the current working directory, that are passed as keyword arguments to the `openbb-api` entry point.
```sh
openbb-api --ssl_keyfile localhost.key --ssl_certfile localhost.crt
```
**Note**: Adjust the command to include the full path to the file if the current working directory is not where they are located.
The certificate - `localhost.crt` - will need to be added to system's trust store. The process for this will depend on the operating system and the user account privilege.
A quick solution is to visit the server's URL, show the details of the warning, and choose to continue anyways.
Contact the system administrator if you are using a work device and require additional permissions to complete the configuration.
![This Connection Is Not Private](https://in.norton.com/content/dam/blogs/images/norton/am/this_connection_not_is_private.png)
## Installed Folder Structure
At the root of the installation (where this document is), there will be three folders:
- conda (Windows: This is named after the last folder path if the default was not used)
- extensions
- notebooks
### Conda
This is the folder where Conda is installed and all environment data (site-packages, etc.) is stored. The "Environments" shortcuts takes you to the root of the "envs" folder.
### Extensions
This folder contains two subfolders:
### Notebooks
This folder contains tutorial notebooks with examples for getting started with Python and the OpenBB Platform. They can be opened by launching the `openbb-notebook` shortcut.
#### examples
Contains empty example extensions for the three types of OpenBB Platform extensions:
- Router
- Provider
- OBBject
To install all three examples in the OpenBB Platform environment, open the Bash/CMD shortcut and enter:
```console
source activate obb # CMD: conda activate obb
cd extensions/examples
python install_examples.py
```
#### openbb_platform_installer
This is a meta package for installing and managing OpenBB Platform installation within any Python environment.
Poetry is used to update and resolve any dependencies that are defined in the `pyproject.toml` file.
The `poetry.lock` file is updated every time the `Update` shortcut is run.
There are several configurations available, via combinations of `--with`, `--without`, and `--only` parameters, when running `poetry install`.
Choices are:
- main
- openbb-all
- cli
- notebook
Each parameter will accept multiple items, but `--without` takes priority for solving for the environment.
## Uninstallation
Mac/Linux users can uninstall by deleting the folder, while Windows users can run the Uninstall shortcut.
The leftover artifacts will include:
- Global configuration files stored by Poetry, PIP, Conda, and Jupyter.
- Third-party Python package caches and `.env` files.
- Folders:
- ~/.openbb_platform
- ~/OpenBBUserData
Windows users will also need to remove the parent folder where it was originally installed, after running Uninstall.
Your OpenBB Hub account can be deleted, along with all associated data, from the Account page in [my.openbb.co](https://my.openbb.co)
## Additional Information
### Conda Install vs. PIP Install vs. Poetry Install
The three ways to install packages may appear to accomplish the same objectives - installing Python packages - but each has a distinctly different purpose.
An easy way to think about the difference is, both `pip` and `poetry` require an existing Python installation; `conda` installs Python so that you can run `pip install poetry`.
In general, you use:
- `conda`
- When a new environment has been created. Packages here can be included in the creation command, `conda create`.
- When the specific package is only distributed through Conda or the `conda-forge` channel.
- When changing the version of Python used within the environment.
- For interactions with the machine code layer of the system - e.g., compilers, and bridges to "outside of Python" land.
- `pip`
- When installing/uninstalling packages to the activated Python environment.
- Resort to `conda install` when packages fail to install, or wheels cannot be built, from PyPI.
- `poetry`
- Installing a local Python package.
- Syncing all package dependencies according to provided specs in `pyproject.toml` and `poetry.lock` files.
- Building and distributing Python packages.
Conda is for container management and machine code level operations, Poetry resolves the project's dependencies and provides build/distribution tools within the current Python environment, while `pip` is for installing Python packages - typically from [PyPI](https://pypi.org).
### Documentation Resources
### OpenBB
- [OpenBB Pro](https://docs.openbb.co/pro)
- [OpenBB Pro Data Connectors](https://docs.openbb.co/pro/data-connector)
- [widgets.json](https://docs.openbb.co/pro/custom-backend/widgets.json)
- [OpenBB Platform](https://docs.openbb.co/platform)
- [OpenBB Platform Quickstart](https://docs.openbb.co/platform/getting_started/quickstart)
- [OpenBB CLI](https://docs.openbb.co/cli)
- [OpenBB User Settings](https://docs.openbb.co/platform/user_guides/settings_and_environment_variables)
- [API Keys and Authorization](https://docs.openbb.co/platform/getting_started/api_keys)
- [REST API Requests](https://docs.openbb.co/platform/getting_started/api_requests)
- [OpenBB Platform Architecture Overview](https://docs.openbb.co/platform/developer_guide/architecture_overview)
- [Create A New Router Extension](https://docs.openbb.co/platform/getting_started/create_new_router_extension)
- [OpenBB Charting](https://github.com/OpenBB-finance/OpenBB/tree/develop/openbb_platform/obbject_extensions/charting#readme)
- [PyWry](https://github.com/OpenBB-finance/pywry)
### External
- [python](https://docs.python.org/3/)
- [conda create](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#managing-environments)
- [pyproject.toml](https://python-poetry.org/docs/pyproject/)
- [requirements.txt](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
- [pip](https://pip.pypa.io/en/stable/)
- [poetry config](https://python-poetry.org/docs/configuration)
- [pydantic](https://docs.pydantic.dev/latest/)
- [uvicorn](https://www.uvicorn.org/)
- [fastapi](https://fastapi.tiangolo.com/)
- [jupyter](https://docs.jupyter.org/en/latest/)
- [pandas](https://pandas.pydata.org/docs/)
- [numpy](https://numpy.org/doc/)
- [Plotly Graph Objects](https://plotly.com/python/graph-objects/)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,70 +0,0 @@
Set objShell = CreateObject("WScript.Shell")
sdesktopPath = objShell.SpecialFolders("Desktop")
Set fso = CreateObject("Scripting.FileSystemObject")
prefixPath = objShell.ExpandEnvironmentStrings("%PREFIX%")
userProfilePath = objShell.ExpandEnvironmentStrings("%USERPROFILE%")
currentPath = fso.GetAbsolutePathName(prefixPath)
parentFolder = fso.GetParentFolderName(currentPath)
shortcutFolder = parentFolder
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FolderExists(shortcutFolder) Then
objFSO.CreateFolder(shortcutFolder)
End If
If prefixPath = "%PREFIX%" Or userProfilePath = "%USERPROFILE%" Then
WScript.Echo "Environment variables %PREFIX% or %USERPROFILE% are not set correctly."
WScript.Quit 1
End If
Sub CreateShortcut(name, targetPath, iconPath)
Set objShell = CreateObject("WScript.Shell")
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\" & name & ".lnk")
objShortcut.TargetPath = objShell.ExpandEnvironmentStrings(targetPath)
objShortcut.IconLocation = objShell.ExpandEnvironmentStrings(iconPath)
objShortcut.Description = name
objShortcut.Save
End Sub
CreateShortcut "openbb-cli", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "openbb-api", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "openbb-notebook", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "openbb-ipython", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "Update", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "CMD", "C:\Windows\System32\cmd.exe", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "Environments", prefixPath & "\envs", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "Settings", userProfilePath & "\.openbb_platform", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "OpenBBUserData", userProfilePath & "\OpenBBUserData", prefixPath & "\assets\openbb_icon.ico"
CreateShortcut "Uninstall", prefixPath & "\Uninstall-OpenBB.exe", prefixPath & "\assets\openbb_icon.ico"
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\openbb-notebook.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate " & prefixPath & "\envs\obb && cd " & shortcutFolder & " && jupyter-notebook && exit"
objShortcut.WorkingDirectory = shortcutFolder
objShortcut.Save
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\openbb-ipython.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate " & prefixPath & "\envs\obb && ipython -c ""from openbb import obb;obb"" -i"
objShortcut.WorkingDirectory = prefixPath
objShortcut.Save
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\openbb-api.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate " & prefixPath & "\envs\obb && call openbb-api --login && exit"
objShortcut.WorkingDirectory = prefixPath
objShortcut.Save
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\Update.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate " & prefixPath & "\envs\obb && call openbb-update && exit"
objShortcut.WorkingDirectory = prefixPath
objShortcut.Save
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\CMD.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate base && echo Conda base environment is active. Use this shell to create new environments. && echo To activate the OpenBB environment, run 'conda activate obb'."
objShortcut.WorkingDirectory = shortcutFolder
objShortcut.Save
Set objShortcut = objShell.CreateShortcut(shortcutFolder & "\openbb-cli.lnk")
objShortcut.Arguments = "/k PATH " & prefixPath & ";" & prefixPath & "\Scripts;" & prefixPath & "\Library\bin;%PATH% && activate " & prefixPath & "\envs\obb && call openbb && exit"
objShortcut.WorkingDirectory = prefixPath
objShortcut.Save

View File

@@ -1,86 +0,0 @@
Page Custom muiExtraPages_Create
!include "FileFunc.nsh"
var IntroText
var InstallationLink
var ExampleImg
var ExampleImgCtl
var PARENTDIR
Function muiExtraPages_Create
Push $0
!insertmacro MUI_HEADER_TEXT_PAGE \
"${PRODUCT_NAME}" \
"Installation Successfully Complete"
${GetParent} "$INSTDIR" $PARENTDIR
nsDialogs::Create /NOUNLOAD 1018
${NSD_CreateLabel} 10u 10u 280u 40u "Click the link below to open the installation folder:"
Pop $IntroText
${NSD_CreateLink} 10u 55u 200u 10u $PARENTDIR
Pop $InstallationLink
${NSD_OnClick} $InstallationLink LaunchLinkOne
nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_BITMAP}|${SS_REALSIZECONTROL} 0 10u 90u 280u 40u ""
Pop $ExampleImgCtl
StrCpy $0 $PLUGINSDIR\openbb_win.png
System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_BITMAP}, i 0, i 0, i ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS}) i.s'
Pop $ExampleImg
SendMessage $ExampleImgCtl ${STM_SETIMAGE} ${IMAGE_BITMAP} $ExampleImg
nsDialogs::Show
System::Call 'gdi32:DeleteObject(i $ExampleImg)'
Pop $0
FunctionEnd
!define MUI_FINISHPAGE_TEXT "Select a resource to open.$\r$\n$\r$\n"
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_TEXT "OpenBB Platform Documentation"
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLinkTwo"
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MyFinishShow
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE MyFinishLeave
var CheckboxLinkThree
var CheckboxLinkFour
Function LaunchLinkOne
ExecShell "open" "$PARENTDIR"
FunctionEnd
Function LaunchLinkTwo
ExecShell "open" "https://docs.openbb.co/platform"
FunctionEnd
Function MyFinishShow
${NSD_CreateCheckbox} 120u 110u 100% 10u "OpenBB CLI Documentation"
Pop $CheckboxLinkThree
${NSD_Check} $CheckboxLinkThree
SetCtlColors $CheckboxLinkThree "" "ffffff"
${NSD_CreateCheckbox} 120u 130u 100% 10u "OpenBB Pro Documentation"
Pop $CheckboxLinkFour
${NSD_Check} $CheckboxLinkFour
SetCtlColors $CheckboxLinkFour "" "ffffff"
FunctionEnd
Function MyFinishLeave
${NSD_GetState} $CheckboxLinkThree $0
${If} $0 <> 0
ExecShell "open" "https://docs.openbb.co/cli"
${EndIf}
${NSD_GetState} $CheckboxLinkFour $0
${If} $0 <> 0
ExecShell "open" "https://docs.openbb.co/pro"
${EndIf}
FunctionEnd
!insertmacro MUI_PAGE_FINISH

View File

@@ -1,41 +0,0 @@
# Below is an example of creating multiple pages after the welcome page of the installer.
#
# This file contains code that is inserted where the @CUSTOM_WELCOME_FILE@ is located
# in the main.nsi.tmpl. The main mechanism for extra pages occurs with the
# "Page Custom muiExtraPagesAfterWelcome_Create" line, which
# references the function "muiExtraPagesAfterWelcome_Create" for page creation.
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipPageIfUACInnerInstance
!insertmacro MUI_PAGE_WELCOME
Page Custom muiExtraPagesAfterWelcome_Create
var IntroAfterWelcomeText
var InstallationAfterWelcomeLink
var ExampleAfterWelcomeImg
var ExampleImgAfterWelcomeCtl
Function muiExtraPagesAfterWelcome_Create
Push $0
!insertmacro MUI_HEADER_TEXT_PAGE \
"${PRODUCT_NAME}" \
"Welcome to OpenBB Platform Installer"
nsDialogs::Create /NOUNLOAD 1018
${NSD_CreateLabel} 10u 10u 280u 120u "Welcome to the OpenBB Platform Installer.$\r$\n$\r$\nThis application will install the latest version of the OpenBB Platform on your computer as a self-contained, Python 3.12, Conda environment.$\r$\n$\r$\nIn order to install you need access to the Internet.$\r$\n$\r$\nInstallation requires between 1-2 GB of storage space, with a minimum of 4GB RAM.$\r$\n$\r$\nWhen a non-default installation path is chosen, it requires a depth of two - i.e, User/MyUserAccount/OpenBB/conda, where OpenBB is the target folder, and conda is the name of the folder where Conda and the installed environments live. The path, including username, should not contain any spaces."
Pop $IntroAfterWelcomeText
nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_BITMAP}|${SS_REALSIZECONTROL} 0 10u 90u 280u 40u ""
Pop $ExampleImgAfterWelcomeCtl
StrCpy $0 $PLUGINSDIR\openbb_win.png
System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_BITMAP}, i 0, i 0, i ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS}) i.s'
Pop $ExampleAfterWelcomeImg
SendMessage $ExampleImgAfterWelcomeCtl ${STM_SETIMAGE} ${IMAGE_BITMAP} $ExampleAfterWelcomeImg
nsDialogs::Show
System::Call 'gdi32:DeleteObject(i $ExampleAfterWelcomeImg)'
Pop $0
FunctionEnd

Binary file not shown.

View File

@@ -1,40 +0,0 @@
# Example Extension Templates
The extensions in this folder represent starting points for creating your own OpenBB extensions. The types of extensions that can be created are:
- Router
- Create a new router path and define the functions for the app.
- Provider
- Add a new data provider source.
- OBBject
- Extend the response object returned by every command.
## Installation
### All Examples
To install all example extensions, activate the environment, then run:
```sh
python install_examples.py
```
### Individual Example
To install an individual extension to the existing OpenBB environment, activate it, then navigate into the folder of the desired extension and enter:
```sh
poetry install --only-root
```
Then, rebuild the OpenBB Python interface with:
```sh
openbb-build
```
The new extension(s) will be available by importing the OpenBB package.
```python
from openbb import obb
```

View File

@@ -1,9 +0,0 @@
# Empty OBBject Extension
This is an empty OpenBB Platform OBBJECT (Response Object) Extension.
Install this extension locally with:
```console
poetry install --only-root
```

View File

@@ -1,30 +0,0 @@
"""Empty OBBject extension."""
import warnings
from openbb_core.app.model.extension import Extension
from openbb_core.app.model.obbject import OBBject
warnings.filterwarnings(
"ignore", lineno=0
) # This suppresses a warning you might see with IPython and OBBject Extensions on import and initialize.
ext = Extension(name="empty")
# OBBject Accessors are used to extend the functionality of the OBBject class.
# The name given to the Extension creates a new namespace in every output object of the Router.
# This is useful for formatting/processing the output of the function calls, where universal application is desired.
@ext.obbject_accessor
class Empty:
"""An Empty OBBject extension."""
def __init__(self, obbject):
"""Creates an instance of the Empty OBBject extension."""
self._obbject: OBBject = obbject
@staticmethod
def hello():
"""Print a greeting message."""
print("Hello from the Empty OBBject extension!") # noqa: T201

View File

@@ -1,18 +0,0 @@
[tool.poetry]
name = "empty-obbject"
version = "0.0.1"
description = "An empty OBBject extension"
authors = ["OpenBB Team <hello@openbb.co>"]
readme = "README.md"
packages = [{ include = "empty_obbject" }]
[tool.poetry.dependencies]
python = ">=3.10,<3.14"
openbb-core = "^1.4.6"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.plugins."openbb_obbject_extension"]
empty = "empty_obbject:ext"

View File

@@ -1,9 +0,0 @@
# Empty Provider Extension
This is an empty OpenBB Platform Provider Extension.
Install this extension locally with:
```console
poetry install --only-root
```

View File

@@ -1,21 +0,0 @@
"""Empty Provider Module."""
# Import the fetchers from each model.
from openbb_core.provider.abstract.provider import Provider
from empty_provider.models.empty_model import EmptyFetcher
empty_provider = Provider(
name="empty",
website="http://empty.io",
description="""The empty provider is a supplier of promises.""",
# credentials=["api_key"], # Credentials added here are mapped to `user_settings.json` in the `credentials` key.
fetcher_dict={
"Empty": EmptyFetcher # The key is the name of the model defined in the @router decorator.
},
)
# Every provider follows this same pattern, so it is possible to import the fetchers from other providers
# and map them to the fetcher_dict above.
# from openbb_yfinance import yfinance_provider
# yfinance_fetchers = yfinance_provider.fetcher_dict.copy()

View File

@@ -1 +0,0 @@
"""Empty Provider Models."""

View File

@@ -1,93 +0,0 @@
"""Empty Fetcher Model. This model is used in conjunction with the 'empty_router' extension."""
# pylint: disable=unused-import
# flake8: noqa: F401
from datetime import (
date as dateType,
datetime,
)
from typing import Any, Dict, Optional
from openbb_core.provider.abstract.data import Data
from openbb_core.provider.abstract.fetcher import Fetcher
from openbb_core.provider.abstract.query_params import QueryParams
from pydantic import Field
class EmptyQueryParams(QueryParams):
"""Empty Query Params"""
some_param: Optional[str] = Field(
default=None,
description="Some param",
)
class EmptyData(Data):
"""Empty Data"""
date: Optional[dateType] = Field(
default=None,
description="Date of the data.",
)
title: Optional[str] = Field(
default=None,
description="Title of the data.",
)
class EmptyFetcher(
Fetcher[
EmptyQueryParams,
EmptyData, # Change the Typing when returning a list of models - i.e, records.
]
):
"""Empty Fetcher."""
@staticmethod
def transform_query(params: Dict[str, Any]) -> EmptyQueryParams:
"""Transform query params."""
transformed_params = params.copy()
# if transformed_params.get("some_param"):
# do something
#
# This is where you can set default values for query parameters.
# Essentially, `@model_validate(mode='before')`.
return EmptyQueryParams(**transformed_params)
@staticmethod
async def aextract_data(
query: EmptyQueryParams,
credentials: Optional[Dict[str, str]],
**kwargs: Any,
) -> Dict: # Typing here should match the 'data' input of 'transform_data'.
"""Extract data."""
# pylint: disable=import-outside-toplevel
# from openbb_core.provider.utils.helpers import (
# make_request,
# amake_request,
# amake_requests,
# get_querystring,
# ) Use these to make HTTP requests.
# We import here so that items are imported on execution, not on initialization.
# Critical for modules that introduce a heavy load on the system.
# Generally, any module required for data retrieval and parsing should be 'lazy' imported.
# This is to ensure that the module is only imported when needed.
print(query.some_param) # noqa: T201
results = {
"date": datetime.now().date(),
"title": "Hello from the Empty Provider extension!",
}
return results
@staticmethod
def transform_data(
query: EmptyQueryParams,
data: Dict, # Typing here matches the output of '(a)extract_data'.
**kwargs: Any,
) -> EmptyData: # Typing here matches the Fetcher's definition.
"""Transform data."""
return EmptyData.model_validate(data)

View File

@@ -1 +0,0 @@
"""Utilities and Helpers."""

View File

@@ -1,18 +0,0 @@
[tool.poetry]
name = "empty-provider"
version = "0.0.1"
description = "Empty provider extension for OpenBB"
authors = ["OpenBB Team <hello@openbb.co>"]
readme = "README.md"
packages = [{ include = "empty_provider" }]
[tool.poetry.dependencies]
python = ">=3.10,<3.14"
openbb-core = "^1.4.6"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.plugins."openbb_provider_extension"]
empty = "empty_provider:empty_provider"

View File

@@ -1,9 +0,0 @@
# Empty Router Extension
This is an empty OpenBB Platform Router Extension.
Install this extension locally with:
```console
poetry install --only-root
```

View File

@@ -1 +0,0 @@
"""An Empty OpenBB Router extension."""

View File

@@ -1,69 +0,0 @@
"""Empty Router Extenision for OpenBB Platform."""
from datetime import datetime
from openbb_core.app.model.command_context import CommandContext
from openbb_core.app.model.example import APIEx, PythonEx
from openbb_core.app.model.obbject import OBBject
from openbb_core.app.provider_interface import (
ExtraParams,
ProviderChoices,
StandardParams,
)
from openbb_core.app.query import Query
from openbb_core.app.router import Router
from openbb_core.provider.abstract.data import Data
router = Router(prefix="", description="An Empty OpenBB Router Extension.")
# The first function call will take longer than the rest, as modules are loaded on the first call.
# Note that all routers must return an instance of `OBBject`, where the output is the `results` attribute.
# This is a standard router "get" command.
@router.command(
methods=["GET"],
examples=[
PythonEx(
description="Say Hello.",
code=[
"result = obb.empty.hello()",
],
),
],
)
async def hello() -> (
OBBject[dict]
): # The output of every router command must be an instance of `OBBject`.
"""OpenBB Hello World."""
return OBBject(
results={
datetime.now().strftime(
"%Y-%m-%d"
): "Hello from the Empty Router extension!"
}
)
# This uses the Provider Interface to call the empty provider fetcher.
@router.command(
model="Empty",
examples=[
APIEx(parameters={"provider": "empty"}),
PythonEx(
description="Say Hello.",
code=[
"result = obb.empty.empty_function()",
],
),
],
)
async def empty_function(
cc: CommandContext,
provider_choices: ProviderChoices,
standard_params: StandardParams,
extra_params: ExtraParams,
) -> OBBject[Data]:
"""An empty function using the Provider Interface."""
return await OBBject.from_query(Query(**locals()))

View File

@@ -1,29 +0,0 @@
"""Views for the Empty Extension."""
# pylint: disable=unused-import
# flake8: noqa: F401
from typing import TYPE_CHECKING, Any, Dict, Tuple
if TYPE_CHECKING:
from openbb_charting.core.openbb_figure import OpenBBFigure
# If `openbb-charting` was installed, this will be used to create a chart.
# Process the data by accessing, "kwargs["obbject_item"]", the function results.
# The return is a Tuple of the OpenBBFigure and a Dict of the data, so it can be
# returned to the Fast API endpoint. Use `fig.to_plotly_json()` to convert the
# OpenBBFigure to a JSON serializable object.
class EmptyViews:
"""Empty Views."""
# @staticmethod
# def empty_hello( # noqa: PLR0912
# **kwargs,
# ) -> Tuple["OpenBBFigure", Dict[str, Any]]:
# """Get Derivatives Price Historical Chart."""
# pylint: disable=import-outside-toplevel
# from openbb_charting.charts.price_historical import price_historical
# return price_historical(**kwargs)

View File

@@ -1,18 +0,0 @@
[tool.poetry]
name = "empty-router"
version = "0.0.1"
description = "An empty OpenBB Router extension"
authors = ["OpenBB Team <hello@openbb.co>"]
readme = "README.md"
packages = [{ include = "empty_router" }]
[tool.poetry.dependencies]
python = ">=3.10,<3.14"
openbb-core = "^1.4.6"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.plugins."openbb_core_extension"]
empty = "empty_router.empty_router:router"

View File

@@ -1,48 +0,0 @@
"""Script to install the example extensions in develop mode to the current Python environment."""
def main():
"""Run the setup script."""
# pylint: disable=import-outside-toplevel
import glob
import os
import subprocess
from pathlib import Path
try:
import openbb # noqa: F401 # pylint: disable=unused-import
except ImportError:
subprocess.check_call("openbb-build", shell=True) # noqa: S602, S607
base_dir = Path(__file__).parent
directories = [
os.path.join(base_dir, d)
for d in os.listdir(base_dir)
if os.path.isdir(os.path.join(base_dir, d))
and glob.glob(os.path.join(base_dir, d, "*.toml"))
]
for directory in directories:
subprocess.check_call(
[ # noqa: S603
os.sys.executable,
"-m",
"poetry",
"install",
"-C",
directory,
"--only-root",
]
)
subprocess.check_call("openbb-build", shell=True) # noqa: S602, S607
print( # noqa: T201
"\nExample extensions have been installed and are ready-to-use."
"\nTo connect the examples to OpenBB Pro and edit the code live, run: openbb-api --reload\n"
)
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,264 +0,0 @@
;--------------------------------
; Includes
!include "MUI2.nsh"
!include "logiclib.nsh"
#if enable_debugging is True
# Special logging build needed for ENABLE_LOGGING
# See https://nsis.sourceforge.io/Special_Builds
!define ENABLE_LOGGING=True
#endif
# Comes from https://nsis.sourceforge.io/Logging:Enable_Logs_Quickly
!define LogSet "!insertmacro LogSetMacro"
!macro LogSetMacro SETTING
!ifdef ENABLE_LOGGING
LogSet ${SETTING}
!endif
!macroend
!define LogText "!insertmacro LogTextMacro"
!macro LogTextMacro INPUT_TEXT
!ifdef ENABLE_LOGGING
LogText ${INPUT_TEXT}
!endif
!macroend
;--------------------------------
; Custom defines
!define NAME "OpenBB Platform"
!define COMPANY "OpenBB"
!define VERSION "1.0.0"
!define SLUG "${NAME} v${VERSION}"
;--------------------------------
; General
Name "${NAME}"
InstallDir "${PROFILE}\OpenBB"
RequestExecutionLevel user
;--------------------------------
; UI
!define MUI_ICON "assets\openbb_icon.ico"
!define MUI_UNICON "assets\openbb_icon.ico"
!define MUI_HEADERIMAGE
!define MUI_WELCOMEFINISHPAGE_BITMAP "assets\installer_vertical2.bmp"
!define MUI_HEADERIMAGE_BITMAP "assets\installer_horizontal.bmp"
!define MUI_ABORTWARNING
!define MUI_WELCOMEPAGE_TITLE "${SLUG} Setup"
!define UninstId "OpenBBPlatform" ; You might want to use a GUID here
;--------------------------------
; Pages
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "assets\installer_license.txt"
; !insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; Uninstaller pages
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
; 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
${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}" "OpenBBPlatform" "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
;--------------------------------
; Remove empty parent directories
Function un.RMDirUP
!define RMDirUP '!insertmacro RMDirUPCall'
!macro RMDirUPCall _PATH
push '${_PATH}'
Call un.RMDirUP
!macroend
; $0 - current folder
ClearErrors
Exch $0
;DetailPrint "ASDF - $0\.."
RMDir "$0\.."
IfErrors Skip
${RMDirUP} "$0\.."
Skip:
Pop $0
FunctionEnd
;--------------------------------
; Section - Uninstaller
Section "Uninstall"
;Delete Shortcut
Delete "$DESKTOP\${NAME}.lnk"
;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"
DeleteRegKey /ifempty HKCU "Software\${NAME}"
SectionEnd

View File

@@ -1,12 +0,0 @@
Thank you for installing OpenBB Platform!
To get started, open the installed OpenBB folder, in the home folder of your user, and review the README.md file. Or, open one of the launchers using the provided shortcuts.
The OpenBB Platform Documentation is found here:
https://docs.openbb.co
Bugs/Issues/Requests can be posted here:
https://github.com/OpenBB-finance/OpenBB/issues
Security vulnerabilities can be reported here:
https://github.com/OpenBB-finance/OpenBB/security/advisories

View File

@@ -1,19 +0,0 @@
OpenBB Platform provides a convenient way to access raw financial data from multiple data providers.
Important Notes:
In order to install you need access to the Internet.
The installation will take approximately 1-2 GB of storage and is for the current user only, system-wide installations are not allowed.
If a folder named "OpenBB" already exists at the user home directory, please remove it before installing.
The installed packages can be reconfigured, post-installation, for custom configurations.
If the OpenBB folder is moved, post-installation, the shortcuts will not be updated to reflect the change.
This application is intended strictly for research and educational purposes.
By proceeding with the installation, you agree not to use this application for any purpose that is unlawful or prohibited by international and national laws, regulations, or governmental and industry requirements.

View File

@@ -1,8 +0,0 @@
Welcome to the OpenBB Platform Installer.
This application will install the latest version of the OpenBB Platform on your computer in a self-contained, Python 3.12, Conda environment. It contains everything required to get started immediately, both as a user and a developer.
Several launch scripts are included; OpenBB CLI, OpenBB API, Jupyter Notebook, IPython, Update, and shortcuts to key folders.
Find them at the base of the installation folder, along with the README.md file for getting started.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -1,48 +0,0 @@
# OpenBB Platform Installer Package
This package is for installing the OpenBB Platform packages into any Python environment. Versions between 3.9 and 3.12, inclusively, are supported.
The `obb` virtual environment that came with the installation is pre-loaded, and this configuration can be duplicated by creating a new environment and running, `poetry install`, from this location.
## Installation
Assuming the current working directory is the location of this document, the code block below will create a new environment, activate it, update the dependencies, and then install the OpenBB Platform.
Open the Terminal command line with the Bash/CMD shortcut.
```sh
conda create -n my_env python=3.10 -y
conda activate my_env
pip install poetry
poetry lock
poetry install
openbb-build
```
## Updating Packages
Update the environment dependencies with:
```sh
poetry lock
poetry install
```
## Installation Groups
The package can be installed in different configurations, using Poetry groups as `--with`, `--without`, or `--only` keyword arguments.
- main
- openbb-all
- cli
- notebook
To install, in a fresh environment, only the `openbb-core` package and the base dependencies:
```sh
poetry install --only main --sync
```
The `--sync` flag with sync the environment to the `poetry.lock` file for the flagged group(s). All items are installed when no arguments are supplied. Use this as a way to restore corrupted environments.
Do not use the `--sync` flag if you wish to keep installed packages that are not defined in the `pyproject.toml` and `poetry.lock` files.

View File

@@ -1,5 +0,0 @@
name: obb
channels:
- conda-forge
dependencies:
- python=3.12

View File

@@ -1,3 +0,0 @@
"""Placeholder for the OpenBB Platform Installer package."""
__version__ = "1.0.2"

View File

@@ -1,30 +0,0 @@
"""Entry point for the OpenBB Updater script."""
# pylint: disable=import-outside-toplevel,unused-import
# flake8: noqa
def main():
"""Update the OpenBB Platform and rebuild the Python interface."""
import os
import sys
import subprocess
from pathlib import Path
args = os.sys.argv[1:].copy() if os.sys.argv[1:] else []
cwd = Path(os.path.dirname(os.path.realpath(__file__))).parent.resolve()
command = (
f"{sys.executable} -m pip install -U pip && "
f"{sys.executable} -m poetry lock && "
f"{sys.executable} -m poetry install {' '.join(args)} && "
"openbb-build"
)
subprocess.run(command, shell=True, cwd=cwd)
input("\nUpdate complete. Press Enter to exit...")
if __name__ == "__main__":
main()

View File

@@ -1,40 +0,0 @@
# If you will be using this as a template for your own package, please change the values accordingly.
[tool.poetry]
name = "openbb_platform_installer" # Change this to your package name
version = "1.0.3" # Change this to your package version
description = "A meta package for installing the OpenBB Platform: Investment research for everyone, anywhere." # Change this to your description
authors = ["OpenBB <hello@openbb.co>"] # Change this to your name and email
license = "AGPL-3.0-only" # This license must be compatible with the OpenBB license
readme = "README.md" # Change this to your README file
homepage = "https://openbb.co" # Change this to your website
repository = "https://github.com/openbb-finance/openbb" # Change this to your repository
documentation = "https://docs.openbb.co" # Change this to your documentation
packages = [{ include = "openbb_platform_installer" }] # Update accordingly - these are build scripts and entry points.
[tool.poetry.scripts]
openbb-update = "openbb_platform_installer.update:main"
[tool.poetry.dependencies]
python = ">=3.10,<3.14"
openbb-platform-api = "^1.1.8"
[tool.poetry.group.openbb-all]
[tool.poetry.group.openbb-all.dependencies]
openbb = { version = "^4.4.4", extras = ["all"] }
[tool.poetry.group.cli]
[tool.poetry.group.cli.dependencies]
openbb-cli = "^1"
[tool.poetry.group.notebook]
[tool.poetry.group.notebook.dependencies]
notebook = "^7"
nbclassic = "^1"
jedi-language-server = "^0.41"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,95 +0,0 @@
name: "OpenBB"
version: "Platform"
company: OpenBB, Inc.
license_file: ./assets/installer_license.txt
installer_type: all
register_python: false # [win]
register_python_default: false # [win]
register_envs: false
initialize_by_default: false
initialize_conda: false
write_condarc: true
default_location_pkg: OpenBB # [osx]
default_prefix_domain_user: "%USERPROFILE%\\OpenBB\\conda" # [win]
default_prefix: "${HOME}/OpenBB" # [linux]
default_prefix: "%USERPROFILE%\\OpenBB\\conda" # [win]
pkg_name: conda
specs:
- conda
- bash # [unix]
- python=3.12
extra_envs:
obb:
environment_file: ./assets/openbb_platform_installer/obb-env.yml
channels:
- conda-forge
condarc:
{channels: [conda-forge],
allow_softlinks: false,
auto_activate_base: false,
always_copy: true,
register_envs: false,
pip_interop_enabled: true}
pkg_domains:
enable_anywhere: false
enable_currentUserHome: true
post_install: post_install.sh # [unix]
post_install: post_install.bat # [win]
extra_files:
# Bundle launcher assets
- ./README.md: ../README.md
- ./assets/openbb_platform_installer/obb-env.yml: ../extensions/openbb_platform_installer/obb-env.yml
- ./assets/openbb_platform_installer/pyproject.toml: ../extensions/openbb_platform_installer/pyproject.toml
- ./assets/openbb_platform_installer/README.md: ../extensions/openbb_platform_installer/README.md
- ./assets/openbb_platform_installer/openbb_platform_installer/__init__.py: ../extensions/openbb_platform_installer/openbb_platform_installer/__init__.py
- ./assets/openbb_platform_installer/openbb_platform_installer/update.py: ../extensions/openbb_platform_installer/openbb_platform_installer/update.py
- ./assets/openbb_icon.ico: assets/openbb_icon.ico # [win]
- ./assets/openbb.icns: ../openbb_icon.icns # [osx]
- ./assets/create_shortcut.vbs: assets/create_shortcut.vbs # [win]
- ./assets/installer_license.txt: assets/installer_license.txt # [win]
- ./assets/installer_vertical2.bmp: assets/installer_vertical2.bmp # [win]
- ./assets/installer_horizontal.bmp: assets/installer_horizontal.bmp # [win]
- ./assets/examples/README.md: ../extensions/examples/README.md
- ./assets/examples/install_examples.py: ../extensions/examples/install_examples.py
- ./assets/examples/empty_provider/pyproject.toml: ../extensions/examples/empty_provider/pyproject.toml
- ./assets/examples/empty_provider/README.md: ../extensions/examples/empty_provider/README.md
- ./assets/examples/empty_provider/empty_provider/__init__.py: ../extensions/examples/empty_provider/empty_provider/__init__.py
- ./assets/examples/empty_provider/empty_provider/models/__init__.py: ../extensions/examples/empty_provider/empty_provider/models/__init__.py
- ./assets/examples/empty_provider/empty_provider/models/empty_model.py: ../extensions/examples/empty_provider/empty_provider/models/empty_model.py
- ./assets/examples/empty_provider/empty_provider/utils/__init__.py: ../extensions/examples/empty_provider/empty_provider/utils/__init__.py
- ./assets/examples/empty_router/pyproject.toml: ../extensions/examples/empty_router/pyproject.toml
- ./assets/examples/empty_router/README.md: ../extensions/examples/empty_router/README.md
- ./assets/examples/empty_router/empty_router/__init__.py: ../extensions/examples/empty_router/empty_router/__init__.py
- ./assets/examples/empty_router/empty_router/empty_router.py: ../extensions/examples/empty_router/empty_router/empty_router.py
- ./assets/examples/empty_router/empty_router/empty_views.py: ../extensions/examples/empty_router/empty_router/empty_views.py
- ./assets/examples/empty_obbject/pyproject.toml: ../extensions/examples/empty_obbject/pyproject.toml
- ./assets/examples/empty_obbject/README.md: ../extensions/examples/empty_obbject/README.md
- ./assets/examples/empty_obbject/empty_obbject/__init__.py: ../extensions/examples/empty_obbject/empty_obbject/__init__.py
- ./assets/examples/python_basics.ipynb: ../notebooks/python_basics.ipynb
- ../../../examples/platform_standardization.ipynb: ../notebooks/how_platform_works.ipynb
icon_image: ../openbb_icon.icns # [osx]
icon_image: ./assets/openbb_icon.ico # [win]
welcome_image: ./assets/openbb_osx.png # [unix]
welcome_image: ./assets/Installer_vertical2.bmp # [win]
header_image: ./assets/Installer_horizontal2.png # [win]
welcome_image_text: "OpenBB Platform"
readme_file: ./assets/installer_readme.txt # [unix]
conclusion_file: ./assets/installer_conclusion.txt # [unix]
welcome_file: ./assets/installer_welcome.txt # [unix]
welcome_file: ./assets/custom_welcome.nsi # [win]
conclusion_file: ./assets/custom_conclusion.nsi # [win]
# Add extra files to the installer - this is another way - was playing with this
temp_extra_files:
- ./assets/Installer_vertical2.bmp: Installer_vertical2.bmp # [win]

View File

@@ -1,61 +0,0 @@
@echo off
echo Installing environment, this may take a few minutes... Watch for changes in post_install_log.txt file at the root of the installation directory.
cd "%PREFIX%\..\extensions\openbb_platform_installer"
PATH %PREFIX%;%PREFIX%\Scripts;%PREFIX%\Library\bin;%PATH%
SET LOG_FILE="%PREFIX%\..\post_install_log.txt"
call "%PREFIX%\Scripts\activate.bat"
call conda activate "%PREFIX%\envs\obb" >> "%LOG_FILE%" 2>&1
python -m pip install -U pip >> "%LOG_FILE%" 2>&1
pip install -U setuptools >> "%LOG_FILE%" 2>&1
pip install poetry >> "%LOG_FILE%" 2>&1
poetry config virtualenvs.path "%PREFIX%\envs" --local >> "%LOG_FILE%" 2>&1
poetry config virtualenvs.create false --local >> "%LOG_FILE%" 2>&1
poetry lock >> "%LOG_FILE%" 2>&1
poetry install >> "%LOG_FILE%" 2>&1
IF ERRORLEVEL 1 (
echo %date% %time% "Error during post-installation: poetry install failed." >> %LOG_FILE%
exit /b 1
) ELSE (
echo %date% %time% "Python environment successfully installed... Building the OpenBB Python interface..." >> %LOG_FILE%
)
echo Python environment successfully installed... Building the OpenBB Python interface...
call openbb-build >> "%LOG_FILE%" 2>&1
IF ERRORLEVEL 1 (
call :log_with_timestamp "Error during post-installation: building OpenBB's Python interface failed."
exit /b 1
) ELSE (
call :log_with_timestamp "OpenBB's Python interface built successfully."
)
cscript "%PREFIX%\assets\create_shortcut.vbs" >> "%LOG_FILE%" 2>&1
IF ERRORLEVEL 1 (
echo %date% %time% "Error during post-installation: creating shortcuts failed." >> %LOG_FILE%
exit /b 1
) ELSE (
echo %date% %time% "Shortcuts created successfully." >> %LOG_FILE%
)
echo Post-installation steps completed successfully.
exit /b 0
goto :eof
REM Function to add timestamp
:log_with_timestamp
echo %date%_%time% %1 >> %LOG_FILE%
goto :eof

View File

@@ -1,158 +0,0 @@
#!/bin/bash
# Setup environment.
export PATH="$PREFIX/bin:$PATH"
LOG_FILE="$PREFIX/../post_install_log.txt"
# Function to add timestamp.
log_with_timestamp() {
echo "$(date '+%Y-%m-%d_%H:%M:%S') $1" >>"$LOG_FILE"
}
cd "$PREFIX/../extensions/openbb_platform_installer" >>"$LOG_FILE" 2>&1
source "$PREFIX/etc/profile.d/conda.sh" && conda activate "$PREFIX"
conda activate obb >>"$LOG_FILE" 2>&1
python -m pip install -U pip >>"$LOG_FILE" 2>&1
pip install -U setuptools poetry >>"$LOG_FILE" 2>&1
pip install poetry >>"$LOG_FILE" 2>&1
poetry config virtualenvs.path "$PREFIX/envs" --local >>"$LOG_FILE" 2>&1
poetry config virtualenvs.create false --local >>"$LOG_FILE" 2>&1
poetry lock >>"$LOG_FILE" 2>&1
# Install OpenBB packages.
if poetry install >>"$LOG_FILE" 2>&1; then
log_with_timestamp "OpenBB Platform installation completed successfully."
else
log_with_timestamp "Error during post-installation: poetry install failed."
exit 1
fi
# Build OpenBB Python interface.
python - <<EOF >>"$LOG_FILE" 2>&1
import openbb
openbb.build()
EOF
log_with_timestamp "OpenBB's Python Interface built successfully."
# IPython launcher script initialized with OpenBB.
IPYTHON_WRAPPER_SCRIPT="$PREFIX/envs/obb/bin/openbb-ipython-launcher"
cat > "$IPYTHON_WRAPPER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
source activate base
conda activate obb
ipython -c "from openbb import obb;obb" -i
EOF
chmod +x "$IPYTHON_WRAPPER_SCRIPT"
# Bash shell isolated for the OpenBB environment.
SHELL_WRAPPER_SCRIPT="$PREFIX/envs/obb/bin/bash"
cat > "$SHELL_WRAPPER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
cd "$PREFIX/.."
source activate base
echo "Conda base environment is active but not initialized. Use this shell to create new environments."
echo "To initialize and activate the OpenBB environment, run 'source activate obb'."
exec $PREFIX/bin/bash -i
EOF
chmod +x "$SHELL_WRAPPER_SCRIPT"
NOTEBOOK_WRAPPER_SCRIPT="$PREFIX/envs/obb/bin/openbb-notebook"
cat > "$NOTEBOOK_WRAPPER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
source activate base
conda activate obb
cd "$PREFIX/.."
jupyter notebook "\$@"
EOF
chmod +x "$NOTEBOOK_WRAPPER_SCRIPT"
API_WRAPPER_SCRIPT="$PREFIX/envs/obb/bin/openbb-api-launcher"
cat > "$API_WRAPPER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
source activate base
conda activate obb
openbb-api --login True "\$@"
EOF
chmod +x "$API_WRAPPER_SCRIPT"
CLI_WRAPPER_SCRIPT="$PREFIX/envs/obb/bin/openbb-cli"
cat > "$CLI_WRAPPER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
source activate base
conda activate obb
openbb "\$@"
EOF
chmod +x "$CLI_WRAPPER_SCRIPT"
OPENBB_UPDATER_SCRIPT="$PREFIX/envs/obb/bin/openbb-updater"
cat > "$OPENBB_UPDATER_SCRIPT" <<EOF
#!$PREFIX/bin/bash
export PATH="$PREFIX/bin:\$PATH"
source activate base
conda activate obb
openbb-update "\$@"
EOF
chmod +x "$OPENBB_UPDATER_SCRIPT"
TARGET_DIR="$PREFIX/.."
mkdir -p "$TARGET_DIR"
if ln -s "$CLI_WRAPPER_SCRIPT" "$TARGET_DIR/openbb-cli" && \
ln -s "$API_WRAPPER_SCRIPT" "$TARGET_DIR/openbb-api" && \
ln -s "$NOTEBOOK_WRAPPER_SCRIPT" "$TARGET_DIR/openbb-notebook" && \
ln -s "$IPYTHON_WRAPPER_SCRIPT" "$TARGET_DIR/openbb-ipython" && \
ln -s "$SHELL_WRAPPER_SCRIPT" "$TARGET_DIR/Bash" && \
ln -s "$OPENBB_UPDATER_SCRIPT" "$TARGET_DIR/Update" && \
ln -s "$HOME/.openbb_platform" "$TARGET_DIR/Settings" && \
ln -s "$PREFIX/envs" "$TARGET_DIR/Environments" && \
ln -s "$HOME/OpenBBUserData" "$TARGET_DIR/OpenBBUserData"; then
log_with_timestamp "Symlinks created successfully." >>"$LOG_FILE" 2>&1
else
log_with_timestamp "Error during post-installation: creating symlinks failed." >>"$LOG_FILE" 2>&1
fi
verify_symlink() {
if [ -L "$1" ] && [ -e "$1" ]; then
log_with_timestamp "Symlink $1 verified successfully."
else
log_with_timestamp "Error: Symlink $1 is not working."
exit 1
fi
}
verify_symlink "$TARGET_DIR/openbb-cli"
verify_symlink "$TARGET_DIR/openbb-api"
verify_symlink "$TARGET_DIR/openbb-notebook"
verify_symlink "$TARGET_DIR/openbb-ipython"
verify_symlink "$TARGET_DIR/Bash"
verify_symlink "$TARGET_DIR/Update"
verify_symlink "$TARGET_DIR/Settings"
verify_symlink "$TARGET_DIR/OpenBBUserData"
verify_symlink "$TARGET_DIR/Environments"

34
desktop/.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
dist/
# Ruff cache
**/*.ruff_cache
# macOS
**/*.DS_Store
*.DS_Store
.DS_Store
# IDE
.vscode/
.idea/
# Tanstack
.tanstack/
# Rust backup files
**/*.rs.bk
# MSVC Windows builds - debugging information
*.pdb
# Node
node_modules/
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*

12026
desktop/Cargo.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff

10
desktop/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,10 @@
[workspace]
resolver = "2"
members = [
"src-tauri",
]
[workspace.dependencies]
openssl = "^0.10.73"

21
desktop/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 OpenBB
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

106
desktop/README.md vendored Normal file
View File

@@ -0,0 +1,106 @@
# Open Data Platform - by OpenBB - Desktop Application
The ODP Desktop Application enhances the developer experience by lowering the technical barriers to entry
for building, presenting, and sharing data pipelines, insights or dashboarding experiences over multiple interfaces.
This code library represents the complete source code for the Open Data Platform (ODP) desktop application and system tray icon, as published by OpenBB.
The distributed binaries (currently macOS and Windows) are the direct output of build actions, located in this repository, responsible for generating release artifacts.
Please note that while there are no build pipelines for a Linux distribution, it is possible to build and install locally.
## User Documentation & Installation
Official user documentation is located [here](https://docs.openbb.co/desktop).
Download the latest version [here](https://github.com/OpenBB-finance/OpenBB/releases/tag/odp)
The remainder of this document is intended for orienting and onboarding to the codebase.
## Stack Overview
ODP Desktop is built with a Tauri & React framework, the code is approximately 50/50, Rust/TypeScript.
This stack reduces the distribution size by relying on the operating system for window creation.
Installed, it is approximately 35 MB; compressed, 12 MB.
The application is tray icon - background service - where functions rely on developer tools that are installed separately via ODP.
In other words, the application itself is a GUI and wrapper for interacting with the operating system and command line.
It is assumed that no developer tools are installed in the operating system, and the user does not have admin/root access to the machine.
Multi-user machines must be configured per-user.
To facilitate environment management and dependency solving, Miniforge is installed when ODP Desktop is first run.
Conda was selected for its effective isolation patterns, as well as platform and language-agnostic qualities.
The initial installation environment provides a production-ready REST API, MCP server, NodeJS, and Jupyter Lab IDE.
## Running Code
Run this code locally from a development server by following the steps below.
### Rust
You must install, or update, Rust to use version 1.90.0
```sh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
If you have previously installed Rust, update to the latest version (currently rustc 1.90.0)
```sh
rustup update
```
### NodeJS
NodeJS and NPM must also be available on $PATH.
Follow the instructions [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) if you do not have it installed.
If you already have `npm`, update it before installing the project.
### OpenSSL
OpenSSL must be installed on the system, with exposed environment variables for:
```env
OPENSSL_DIR
OPENSSL_INCLUDE_DIR
OPENSSL_LIB_DIR
```
### Install Project
With those three, items installed and updated, install the project by running the command from the `/desktop` root folder.
```sh
npm install
```
### Develop
Build and start the development server:
```sh
npm run tauri dev
```
This will start the development server and watch for changes to the codebase. Most changes will be picked up, but some events may require a full restart.
If you use a browser, instead of the window, to view the development server there will be stuff that just doesn't work. This is expected.
Ignore all of the warning messages for now, we'll clean those up later.
### Helpful VS Code Extension
- rust-analyzer
- Tauri
- Tailwind CSS IntelliSense
## Building
Production builds are intended to be completed and signed via GitHub actions. Adjustments to `beforeBundleCommand` may be required for builds outside of the official release structure.

1
desktop/dist/.gitkeep vendored Normal file
View File

@@ -0,0 +1 @@

81
desktop/eslint.config.mjs vendored Normal file
View File

@@ -0,0 +1,81 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import react from "eslint-plugin-react";
export default [
{
ignores: [
"dist/",
"target/",
"node_modules/",
"*.js",
"*.cjs",
"*.mjs",
"*.d.ts",
"src-tauri/",
".vscode/",
".tanstack/"
]
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
plugins: { "@typescript-eslint": tseslint.plugin },
languageOptions: {
parser: tseslint.parser,
parserOptions: {
project: "./tsconfig.json",
},
globals: {
window: "readonly",
document: "readonly",
console: "readonly",
setTimeout: "readonly",
clearTimeout: "readonly",
setInterval: "readonly",
clearInterval: "readonly",
Event: "readonly",
CustomEvent: "readonly",
Node: "readonly",
HTMLElement: "readonly",
HTMLInputElement: "readonly",
ResizeObserver: "readonly",
MutationObserver: "readonly",
AbortController: "readonly",
URL: "readonly",
Headers: "readonly",
Response: "readonly",
CSS: "readonly",
self: "readonly",
navigator: "readonly",
sessionStorage: "readonly",
requestAnimationFrame: "readonly",
cancelAnimationFrame: "readonly",
NodeFilter: "readonly",
DocumentFragment: "readonly",
IntersectionObserver: "readonly",
}
},
},
{
files: ["src/components/BackendLogsPage.tsx", "src/routes/backends.tsx"],
rules: {
"no-control-regex": "off",
},
},
{
plugins: { react },
files: ["**/*.jsx", "**/*.tsx"],
settings: { react: { version: "detect" } },
rules: {
// Add custom React rules here if needed
},
},
{
files: ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts", "**/*.spec.tsx", "**/tests/**/*.ts", "**/tests/**/*.tsx"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
},
];

14
desktop/index.html vendored Normal file
View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/assets/icons/icon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenBB Platform</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

11770
desktop/package-lock.json generated vendored Normal file

File diff suppressed because it is too large Load Diff

71
desktop/package.json vendored Normal file
View File

@@ -0,0 +1,71 @@
{
"name": "openbb-platform",
"private": true,
"version": "0.4.0",
"type": "module",
"license": "AGPL-3.0",
"scripts": {
"dev": "vite --port 1470",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri",
"test": "vitest",
"test:watch": "vitest --watch",
"lint": "eslint src --ext .ts,.tsx,.js,.jsx"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"@hookform/resolvers": "^3.10.0",
"@openbb/ui-pro": "^0.6.10",
"@tanstack/react-router": "^1.131.27",
"@tanstack/router-core": "^1.114.33",
"@tanstack/router-devtools": "^1.131.27",
"@tauri-apps/plugin-app": "^2.0.0-alpha.1",
"@tauri-apps/plugin-dialog": "^2.3.3",
"@tauri-apps/plugin-fs": "^2.4.2",
"@tauri-apps/plugin-http": "^2.5.2",
"@tauri-apps/plugin-log": "^2.6.0",
"@tauri-apps/plugin-opener": "^2.5.0",
"@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-updater": "^2.9.0",
"clsx": "^2.1.1",
"csstype": "^3.1.3",
"date-fns": "^4.1.0",
"postcss": "^8.5.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.62.0",
"react-markdown": "^8.0.7",
"react-select": "^5.10.2",
"tailwindcss": "^3.4.17",
"taurpc": "^1.8.1",
"tiny-invariant": "^1.3.3",
"vite-plugin-static-copy": "^2.3.2",
"zod": "^3.25.76"
},
"devDependencies": {
"@eslint/js": "^9.31.0",
"@tanstack/router-vite-plugin": "^1.131.27",
"@tauri-apps/api": "^2.8.0",
"@tauri-apps/cli": "^2.8.1",
"@tauri-apps/plugin-shell": "^2.3.1",
"@tauri-apps/plugin-window": "^2.0.0-alpha.1",
"@testing-library/jest-dom": "^6.7.0",
"@testing-library/react": "^16.3.0",
"@types/node": "^20.19.11",
"@types/react": "^18.3.23",
"@types/react-dom": "^18.3.7",
"@typescript-eslint/eslint-plugin": "^8.37.0",
"@typescript-eslint/parser": "^8.37.0",
"@vitejs/plugin-react": "^4.7.0",
"autoprefixer": "^10.4.21",
"eslint": "^9.33.0",
"eslint-plugin-react": "^7.37.5",
"jsdom": "^26.1.0",
"typescript": "^5.9.2",
"typescript-eslint": "^8.40.0",
"vite": "^6.3.6",
"vite-plugin-svgr": "^4.3.0",
"vitest": "^3.2.4"
}
}

6
desktop/postcss.config.js vendored Normal file
View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

0
desktop/public/.gitkeep vendored Normal file
View File

280
desktop/public/assets/icons/sprite.svg vendored Normal file
View File

@@ -0,0 +1,280 @@
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol viewBox="0 0 24 24" id="image-outline">
<path fill="currentColor" d="M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h14q.825 0 1.413.588T21 5v14q0 .825-.587 1.413T19 21zm0-2h14V5H5zm1-2h12l-3.75-5l-3 4L9 13zm-1 2V5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="plus">
<path fill="currentColor" fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd"/>
</symbol>
<symbol viewBox="0 0 20 20" id="paste">
<path fill="currentColor" fill-rule="evenodd" d="M8 3a1 1 0 011-1h2a1 1 0 110 2H9a1 1 0 01-1-1z" clip-rule="evenodd"/>
<path fill="currentColor" fill-rule="evenodd" d="M6 3a2 2 0 00-2 2v11a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z" clip-rule="evenodd"/>
</symbol>
<symbol viewBox="0 0 24 24" id="chevron-down">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</symbol>
<symbol viewBox="0 0 24 24" id="edit">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"/>
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 23h10"/>
</symbol>
<symbol viewBox="0 0 24 24" id="logs">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2h-3l-4 4z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="logs-icon">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"/>
</symbol>
<symbol viewBox="0 0 24 24" id="stop">
<rect x="6" y="6" width="12" height="12" stroke="currentColor" stroke-width="2"/>
</symbol>
<symbol viewBox="0 0 24 24" id="api-docs">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2 3 3 0 01-3 3H9a3 3 0 01-3-3z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="openapi">
<path d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2 3 3 0 01-3 3H9a3 3 0 01-3-3z" fill="currentColor"/>
</symbol>
<symbol viewBox="0 0 24 24" id="widgets">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"/>
</symbol>
<symbol viewBox="0 0 20 20" id="delete">
<path fill="currentColor" fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/>
</symbol>
<symbol viewBox="0 0 24 24" id="close">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</symbol>
<symbol viewBox="0 0 17 16" id="file-upload">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8.5 3.333v9.334M3.833 8h9.334"/>
</symbol>
<symbol id="refresh" viewBox="0 0 14 14">
<path
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M11.93 7.521a4.958 4.958 0 0 1-9.225 1.958l-.145-.252m-.491-2.748a4.958 4.958 0 0 1 9.225-1.958l.146.252M2.038 10.54l.427-1.594 1.593.427m5.883-4.744 1.594.427.427-1.593"
/>
</symbol>
<symbol id="settings" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M11 17a1 1 0 001.447.894l4-2A1 1 0 0017 15V9.236a1 1 0 00-1.447-.894l-4 2a1 1 0 00-.553.894V17zM15.211 6.276a1 1 0 000-1.788l-4.764-2.382a1 1 0 00-.894 0L4.789 4.488a1 1 0 000 1.788l4.764 2.382a1 1 0 00.894 0l4.764-2.382zM4.447 8.342A1 1 0 003 9.236V15a1 1 0 00.553.894l4 2A1 1 0 009 17v-5.764a1 1 0 00-.553-.894l-4-2z"
/>
</symbol>
<symbol viewBox="0 0 14 14" id="check">
<path
d="M11.6667 3.5L5.25001 9.91667L2.33334 7"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</symbol>
<symbol id="python" viewBox="0 0 24 24">
<path
d="M11.93 2c-5.52.1-5.72 1.9-5.72 3.78v2.77h5.77v.78H4.45s-2.45.28-2.45 3.6c0 3.35 2.14 3.23 2.14 3.23h1.27v-1.57s-.07-1.88 1.85-1.88h5.7s1.92.03 1.92-1.85V4.12S15.55 2 11.93 2zM9.3 3.71c.58 0 1.04.47 1.04 1.05 0 .58-.46 1.05-1.04 1.05-.57 0-1.04-.47-1.04-1.05 0-.58.47-1.05 1.04-1.05z"
fill="#387EB8"
/>
<path
d="M12.07 22c5.53-.1 5.73-1.9 5.73-3.78v-2.77h-5.78v-.78h7.54s2.45-.28 2.45-3.6c0-3.35-2.14-3.23-2.14-3.23h-1.27v1.57s.07 1.88-1.86 1.88h-5.69s-1.92-.03-1.92 1.85v3.13S8.45 22 12.07 22zm2.64-1.71c-.58 0-1.04-.47-1.04-1.05 0-.58.46-1.05 1.04-1.05.57 0 1.04.47 1.04 1.05 0 .58-.47 1.05-1.04 1.05z"
fill="#FFD43B"
/>
</symbol>
<symbol id="stop" viewBox="0 0 20 20">
<rect width="12" height="12" x="4" y="4" rx="1" />
</symbol>
<symbol id="search" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
fill="none"
stroke="currentColor"
/>
</symbol>
<symbol id="folder-icon" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="0.5"
d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
fill="currentColor"
stroke="currentColor"
/>
</symbol>
<symbol id="terminal" viewBox="0 0 24 24">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
fill="none"
stroke="currentColor"
/>
</symbol>
<symbol id="update" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" fill="none" stroke="currentColor"/>
</symbol>
<symbol id="delete-extension" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" fill="none" stroke="currentColor"/>
</symbol>
<symbol id="cancel" viewBox="0 0 20 20">
<path
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clipRule="evenodd"
fill="currentColor"
/>
</symbol>
<symbol id="ipy" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 721 327">
<path fill="currentColor" d="M219 43c107.286 0 107.286 0 125 16 13.823 15.519 14.884 32.996 14.19 52.893-1.095 17.844-9.61 32.244-22.495 44.255C310.958 177.318 279.927 175 249 175v89h-30V43Zm30 22v88c32.672 1.068 32.672 1.068 62.172-11.898 10.333-10.76 14.82-24.582 15.203-39.29-.263-9.881-2.738-18.297-9.375-25.812-18.74-15.634-45.469-11-68-11ZM26 43h134v22h-52v177h52v22H26v-22h52V65H26V43ZM484 114h22a2705603778.712 2705603778.712 0 0 0 10.507 23.952 4799.306 4799.306 0 0 0 12.028 27.236l3.102 6.97a1779.73 1779.73 0 0 0 1.979 4.422c.916 2.042 1.827 4.086 2.736 6.13.513 1.149 1.027 2.296 1.557 3.479C539 189 539 189 539 192h2l.531-1.683a142.016 142.016 0 0 1 6.024-15.454l1.025-2.274c.722-1.6 1.446-3.2 2.171-4.8 1.912-4.214 3.811-8.435 5.71-12.656l1.158-2.574c4.282-9.532 8.422-19.125 12.533-28.732l1.504-3.503 1.307-3.06C574 115 574 115 575 114a62.92 62.92 0 0 1 4.254-.098l2.588.01 2.72.025 2.733.014c2.235.012 4.47.028 6.705.049-3.366 9.168-7.19 18.024-11.299 26.876-1.784 3.847-3.553 7.7-5.322 11.554l-1.106 2.408c-3.785 8.252-7.472 16.548-11.148 24.85l-1.96 4.417-.992 2.236-1.001 2.257-1.008 2.27a88577.834 88577.834 0 0 1-4.324 9.748 6282.16 6282.16 0 0 1-7.281 16.355 2114.19 2114.19 0 0 0-2.33 5.24c-13.632 30.768-13.632 30.768-27.37 37.098-3.834 1.426-7.186 1.811-11.28 1.789l-3.106-.01-3.223-.026-3.27-.013c-2.66-.012-5.32-.03-7.98-.049v-15l4.348-.48c1.905-.235 3.81-.47 5.714-.708l2.858-.306c6.113-.788 10.728-1.963 15.08-6.506 1.725-2.34 3.038-4.768 4.313-7.375l1.01-1.922c.959-1.876 1.821-3.778 2.677-5.703l1.566-3.152c.715-6.343-2.306-11.387-4.941-17.036-.597-1.321-1.192-2.644-1.786-3.967-1.269-2.824-2.55-5.643-3.839-8.458a1173.51 1173.51 0 0 1-5.906-13.172l-.986-2.228-1.986-4.486c-1.668-3.765-3.344-7.528-5.02-11.29a186389.275 186389.275 0 0 1-5.182-11.635c-2.14-4.805-4.277-9.613-6.409-14.422-.67-1.512-1.342-3.022-2.016-4.532-.929-2.084-1.853-4.169-2.776-6.255l-1.596-3.59C484 116 484 116 484 114Z" />
<path
fill="#3A5F96"
d="M408 67h56v16h-39v166h39v16h-56V67ZM604 67h56v198h-56v-16h40V83h-40V67ZM714 205c3.179 1.644 5.378 3.756 7 7 1.03 9.008 1.03 9.008-1.047 13.023-2.478 2.988-4.467 4.807-8.344 5.25-8.669.308-8.669.308-12.234-2.648-3.833-4.236-3.764-7.277-3.734-12.852.556-4.294 2.19-5.906 5.359-8.773 3.963-1.981 8.692-1.558 13-1ZM714 107c3.179 1.644 5.378 3.756 7 7 1.03 9.008 1.03 9.008-1.047 13.023-2.478 2.988-4.467 4.807-8.344 5.25-8.669.308-8.669.308-12.234-2.648-3.833-4.236-3.764-7.277-3.734-12.852.556-4.294 2.19-5.906 5.359-8.773 3.963-1.981 8.692-1.558 13-1Z"
/>
</svg>
</symbol>
<symbol id="jupyter" viewBox="0 0 24 24">
<path d="M12 12m-20 0a20 20 0 1 0 40 0a20 20 0 1 0 -40 0" fill="none" />
<path d="M12 4a8 8 0 100 16 8 8 0 000-16z" fill="none" />
<path d="M7.5 12a5 5 0 1 0 10 0 5 5 0 1 0 -10 0" fill="#F37726" />
<path d="M16.5 12a5 5 0 1 0 10 0 5 5 0 1 0 -10 0" fill="#4E4E4E" />
<path d="M12 6.5a5 5 0 1 0 10 0 5 5 0 1 0 -10 0" fill="#767677" />
</symbol>
<symbol id="setting" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 14 14">
<g stroke="#fff" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" clip-path="url(#a)">
<path d="M7 8.75a1.75 1.75 0 1 0 0-3.5 1.75 1.75 0 0 0 0 3.5Z"/>
<path d="M10.924 8.591a.875.875 0 0 0 .175.965l.032.032a1.061 1.061 0 1 1-1.5 1.5l-.033-.031a.875.875 0 0 0-.965-.175.875.875 0 0 0-.53.8v.09a1.06 1.06 0 1 1-2.121 0v-.047a.875.875 0 0 0-.573-.8.875.875 0 0 0-.965.174l-.032.032a1.06 1.06 0 0 1-1.812-.75 1.06 1.06 0 0 1 .311-.75l.032-.032a.875.875 0 0 0 .175-.966.875.875 0 0 0-.8-.53h-.09a1.06 1.06 0 1 1 0-2.121h.047a.875.875 0 0 0 .8-.573.875.875 0 0 0-.174-.965l-.032-.032a1.06 1.06 0 1 1 1.5-1.5l.033.031a.875.875 0 0 0 .965.175h.042a.875.875 0 0 0 .53-.8v-.09a1.06 1.06 0 0 1 2.122 0v.047a.875.875 0 0 0 .53.8.875.875 0 0 0 .965-.174l.032-.032a1.06 1.06 0 1 1 1.5 1.5l-.031.033a.875.875 0 0 0-.175.965v.042a.875.875 0 0 0 .8.53h.09a1.06 1.06 0 1 1 0 2.122h-.047a.875.875 0 0 0-.8.53Z"/>
</g>
<defs>
<clipPath id="a"><path fill="#fff" d="M0 0h14v14H0z"/></clipPath>
</defs>
</symbol>
<symbol id="upload" viewBox="0 0 16 16">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M2.667 10.828a3 3 0 0 1 1.386-5.482 4.001 4.001 0 0 1 7.894 0 3 3 0 0 1 1.386 5.482m-8 .505L8 14m0 0 2.667-2.667M8 14V8"
fill="none"
/>
</symbol>
<symbol id="jupyter-logo"
xmlns="http://www.w3.org/2000/svg" width="256" height="300" preserveAspectRatio="xMidYMid" viewBox="0 0 256 300">
<g>
<path fill="currentColor" d="M10.584 156.41v-32.753h7.136v35.256a21.302 21.302 0 0 1-4.686 15.976A18.213 18.213 0 0 1 .89 179.31l-.745-5.325a11.61 11.61 0 0 0 7.775-2.982c1.917-2.237 2.663-5.273 2.663-14.592Zm53.22-4.201c0 3.994 0 7.562.32 10.651h-6.338l-.426-6.337a14.752 14.752 0 0 1-12.941 7.242c-6.178 0-13.527-3.355-13.527-17.041v-22.74h7.136v21.302c0 7.402 2.29 12.355 8.734 12.355a9.958 9.958 0 0 0 10.065-10.065v-23.859h7.136v28.279l-.16.213Zm13.527-15.555c0-4.953 0-9-.32-12.675h6.39l.32 6.657a15.445 15.445 0 0 1 13.953-7.562c9.48 0 16.616 7.935 16.616 19.757 0 13.953-8.574 20.877-17.84 20.877a13.794 13.794 0 0 1-12.09-6.125v21.302h-7.03V136.654Zm7.03 10.385c.019.966.126 1.928.319 2.875a10.97 10.97 0 0 0 10.651 8.255c7.509 0 11.93-6.124 11.93-15.018 0-7.775-4.155-14.432-11.664-14.432a12.249 12.249 0 0 0-11.237 11.663v6.657Zm42.644-23.095 8.574 22.953a132.673 132.673 0 0 1 2.503 7.935c.745-2.344 1.544-5.326 2.503-8.095l7.775-22.793h7.509l-10.651 27.692c-5.326 13.314-8.574 20.184-13.474 24.338a19.385 19.385 0 0 1-8.734 4.58l-1.757-5.965a18.906 18.906 0 0 0 6.23-3.461 21.302 21.302 0 0 0 6.019-7.882c.29-.53.488-1.107.585-1.704a6.125 6.125 0 0 0-.479-1.864l-14.485-35.84h7.775l.107.106Zm47.809-11.173v11.183h10.225v5.326h-10.225v20.983c0 4.793 1.384 7.562 5.325 7.562 1.4.023 2.796-.138 4.154-.48l.32 5.326a17.575 17.575 0 0 1-6.338.959 9.906 9.906 0 0 1-7.722-2.983 14.326 14.326 0 0 1-2.77-10.118v-21.302h-6.07V123.9h6.177v-9.48l6.924-1.65Zm23.37 31.877a12.516 12.516 0 0 0 13.474 13.473 25.988 25.988 0 0 0 10.651-2.024l1.225 5.326a31.953 31.953 0 0 1-13.048 2.396 18.106 18.106 0 0 1-19.278-19.598c0-11.716 6.976-20.982 18.373-20.982 12.781 0 15.977 11.183 15.977 18.32.068 1.1.068 2.202 0 3.302h-27.533l.16-.213Zm20.877-5.326a10.064 10.064 0 0 0-9.906-11.503 11.77 11.77 0 0 0-10.917 11.503h20.823Zm17.324-3.269c0-4.58 0-8.52-.32-12.142h6.391v7.616h.32a11.77 11.77 0 0 1 10.651-8.521 7.775 7.775 0 0 1 2.024 0v6.657a10.645 10.645 0 0 0-2.45 0 9.958 9.958 0 0 0-9.533 9.053c-.199 1.09-.306 2.194-.32 3.302v20.716h-7.029v-26.627l.266-.054Z"/>
<path fill="#767677" d="M233.258 16.962a18.053 18.053 0 1 1-18.8-16.935 17.84 17.84 0 0 1 18.8 16.935Z"/>
<path fill="#F37726" d="M127.953 225.541c-47.93 0-90.055-17.201-111.836-42.604a119.239 119.239 0 0 0 223.672 0c-21.728 25.403-63.693 42.604-111.836 42.604ZM127.953 60.354c47.93 0 90.055 17.202 111.836 42.604a119.243 119.243 0 0 0-111.836-77.88 119.239 119.239 0 0 0-111.836 77.88c21.781-25.455 63.694-42.604 111.836-42.604Z"/>
<path fill="#9E9E9E" d="M61.972 274.975a22.74 22.74 0 1 1-23.699-21.302 22.527 22.527 0 0 1 23.699 21.302Z"/>
<path fill="#616262" d="M21.564 54.565a13.102 13.102 0 1 1 12.728-13.633 13.26 13.26 0 0 1-12.728 13.633Z"/>
</g>
</symbol>
<symbol id="bin" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 14 14"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.25 0.75H7.75M0.75 2.5H11.25M10.0833 2.5L9.67425 8.63625C9.61287 9.5569 9.58219 10.0172 9.38334 10.3663C9.20828 10.6735 8.94422 10.9206 8.62597 11.0748C8.26448 11.25 7.80314 11.25 6.88045 11.25H5.11955C4.19686 11.25 3.73552 11.25 3.37403 11.0748C3.05577 10.9206 2.79172 10.6735 2.61666 10.3663C2.41781 10.0172 2.38713 9.5569 2.32575 8.63625L1.91667 2.5"/>
</symbol>
<symbol id="copy" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<g clip-path="url(#a)">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width=".667" d="M6.444 6.444V5.355c0-.435 0-.653.085-.82a.778.778 0 0 1 .34-.34c.167-.084.384-.084.82-.084h2.956c.435 0 .653 0 .82.085a.778.778 0 0 1 .34.34c.084.166.084.384.084.82V8.31c0 .435 0 .653-.085.82a.778.778 0 0 1-.34.34c-.166.084-.384.084-.82.084H9.556m-4.2 2.334H8.31c.436 0 .654 0 .82-.085a.777.777 0 0 0 .34-.34c.085-.166.085-.384.085-.82V7.69c0-.436 0-.654-.085-.82a.778.778 0 0 0-.34-.34c-.166-.085-.384-.085-.82-.085H5.356c-.436 0-.654 0-.82.085a.778.778 0 0 0-.34.34c-.085.166-.085.384-.085.82v2.955c0 .436 0 .654.085.82a.777.777 0 0 0 .34.34c.166.085.384.085.82.085Z"/>
</g>
</symbol>
<symbol id="success" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path fill="currentColor" fill-rule="evenodd" d="M12 21.6a9.6 9.6 0 100-19.2 9.6 9.6 0 000 19.2zm4.448-11.152a1.2 1.2 0 00-1.697-1.697l-2.76 2.76-1.552-1.552a1.2 1.2 0 00-1.697 1.697l2.4 2.4a1.2 1.2 0 001.697 0l4.8-4.8z" clip-rule="evenodd"/>
</symbol>
<symbol id="pencil" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34a.9959.9959 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
/>
</symbol>
<symbol id="documentation" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/>
</symbol>
<symbol id="search" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</symbol>
<symbol id="warning" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a1.999 1.999 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0v0ZM12 9v4M12 17h.01"
/>
</symbol>
<symbol id="info" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z"
fill="none"
/>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M12 16v-4M12 8h.01"
/>
</symbol>
<symbol id="clipboard" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"
/>
</symbol>
<symbol id="eye" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
fill="none"
/>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
fill="none"
/>
</symbol>
<symbol id="eye-off" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"
fill="none"
/>
</symbol>
<symbol id="dashboard" viewBox="0 0 24 24">
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M3 12h7m-7 4h7m-7-8h7m4 0h4m-4 4h4m-4 4h4"
fill="none"
/>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M3 3h18v18H3z"
fill="none"
/>
</symbol>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

4
desktop/src-tauri/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

79
desktop/src-tauri/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,79 @@
[package]
name = "openbb-platform"
version = "0.4.0"
description = "Open Data Platform - by OpenBB - Desktop Application for managing virtual environments, application backend servers."
authors = ["OpenBB, Inc."]
license = "AGPL-3.0"
repository = "https://github.com/OpenBB-finance/OpenBB/"
default-run = "openbb-platform"
edition = "2024"
rust-version = "1.90.0"
[build-dependencies]
tauri-build = { version = "2.4.0", features = [] }
[dependencies]
tokio = { version = "^1.47.1", features = ["full", "test-util"] }
serde_json = { version = "^1.0.143", features = ["preserve_order"] }
serde_yaml = "^0.9"
chrono = "^0.4"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.8.2", features = ["tray-icon", "devtools"] }
tauri-cli = "^2.8.0"
tauri-plugin-log = "2.6.0"
regex = "^1.11.1"
reqwest = { version = "^0.12.23", features = ["json"] }
once_cell = "^1.21.3"
open = "^5.3"
ctrlc = "^3.4.7"
futures = "^0.3.31"
tauri-plugin-shell = "2"
url = "^2.5.4"
urlencoding = "^2.1.3"
uuid = { version = "^1.18.0", features = ["v4"] }
toml = "^0.9.5"
futures-util = "0.3"
futures-channel = "0.3"
tokio-tungstenite = "0.27.0"
fs2 = "0.4.3"
cc = "1.2.33"
dirs = "^6.0.0"
tauri-plugin-dialog = "2"
tauri-plugin-persisted-scope = "2"
tauri-plugin-fs = "2"
mockall = "^0.13.1"
openssl = { workspace = true }
tauri-plugin-opener = "2"
which = "8.0.0"
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs" }
[target.'cfg(linux)'.dependencies]
glib = "^0.21.1"
[target.'cfg(target_os= "macos")'.dependencies]
objc_exception = "0.1"
objc = { version = "0.2.7", features = ["exception"] }
objc2 = "*"
objc2-app-kit = "*"
objc2-foundation = { version = "*", features = ["NSGeometry"] }
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser", "objbase", "shobjidl_core", "shlobj", "combaseapi", "unknwnbase", "objidl", "wtypesbase", "winerror", "minwindef", "wtypes", "oleauto"] }
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-single-instance = "2"
tauri-plugin-updater = "2"
[features]
# This feature depends on the Tauri CLI & CLI plugin for updater
# By default Tauri runs in production mode
# when the `dev` profile is used, it runs in development mode
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]
[[bin]]
name = "openbb-platform"
path = "src/main.rs"

View File

@@ -1,11 +1,15 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (c) 2021-2025 OpenBB Inc.
All files in this repository are licensed under the GNU Affero General Public License v3.0.
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
@@ -56,7 +60,7 @@ this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
TERMS AND CONDITIONS
1. Definitions.
@@ -616,9 +620,9 @@ an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it

3
desktop/src-tauri/build.rs vendored Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

View File

@@ -0,0 +1,22 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"*"
],
"permissions": [
"core:default",
"dialog:default",
"opener:default",
"shell:allow-open",
"shell:default",
"opener:allow-open-url",
"fs:read-all",
"fs:write-all",
"fs:write-files",
"fs:allow-watch",
"fs:allow-unwatch",
"log:default"
]
}

View File

@@ -0,0 +1,73 @@
{
"identifier": "desktop-capability",
"platforms": [
"macOS",
"windows",
"linux"
],
"windows": [
"*"
],
"permissions": [
"core:default",
"opener:allow-default-urls",
"shell:allow-open",
"shell:allow-execute",
"shell:allow-spawn",
"fs:read-all",
"fs:write-all",
"fs:write-files",
"fs:allow-unwatch",
"log:default",
{
"identifier": "opener:allow-open-path",
"allow": [
{
"path": "**"
}
]
},
"dialog:default",
"fs:default",
{
"identifier": "fs:allow-exists",
"allow": [
{
"path": "**"
}
]
},
"fs:scope-home-recursive",
"fs:allow-copy-file",
"fs:allow-create",
"fs:allow-exists",
"fs:allow-mkdir",
"fs:allow-read-dir",
"fs:allow-read-file",
"fs:allow-remove",
"fs:allow-rename",
"fs:allow-watch",
"fs:allow-write-file",
"fs:scope-localdata-recursive",
"fs:scope-log",
"fs:allow-appconfig-read-recursive",
"fs:allow-appconfig-write-recursive",
"fs:allow-app-read-recursive",
"fs:allow-app-write-recursive",
"fs:allow-applocaldata-read-recursive",
"fs:allow-applocaldata-write-recursive",
"fs:allow-applog-read-recursive",
"fs:allow-applog-write-recursive",
"fs:allow-appcache-read-recursive",
"fs:allow-appcache-write-recursive",
"fs:allow-cache-read-recursive",
"fs:allow-cache-write-recursive",
"fs:allow-temp-read-recursive",
"fs:allow-temp-write-recursive",
"fs:allow-data-write-recursive",
"fs:allow-data-read-recursive",
"fs:allow-config-read-recursive",
"fs:allow-config-write-recursive",
"updater:default"
]
}

24
desktop/src-tauri/entitlements.plist vendored Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<false/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.all</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<!-- Allow executing shell scripts -->
<key>com.apple.security.automation.apple-events</key>
<true/>
<!-- Allow background tasks -->
<key>com.apple.security.application-groups</key>
<array>
<string>group.co.openbb.platform</string>
</array>
</dict>
</plist>

BIN
desktop/src-tauri/frameworks/libcrypto.3.dylib vendored Executable file

Binary file not shown.

BIN
desktop/src-tauri/frameworks/libssl.3.dylib vendored Executable file

Binary file not shown.

0
desktop/src-tauri/gen/.gitkeep vendored Normal file
View File

BIN
desktop/src-tauri/icons/128x128.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
desktop/src-tauri/icons/128x128@2x.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
desktop/src-tauri/icons/32x32.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

BIN
desktop/src-tauri/icons/64x64.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 B

BIN
desktop/src-tauri/icons/StoreLogo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

BIN
desktop/src-tauri/icons/icon.icns vendored Normal file

Binary file not shown.

BIN
desktop/src-tauri/icons/icon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
desktop/src-tauri/icons/icon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

5
desktop/src-tauri/icons/icon.svg vendored Normal file
View File

@@ -0,0 +1,5 @@
<svg width="219" height="219" viewBox="0 0 219 219" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" width="218" height="218" rx="32" fill="#006699"/>
<path d="M124.499 133.189V128.251H169.508V138.126H124.499V133.189ZM124.499 93.6886V88.7515H179.501V98.6257H124.499V93.6886ZM184.5 78.8742H114.5V148H179.501V118.374H124.499V108.5H189.5V78.8742H184.5ZM49.4985 133.189V128.251H94.5072V138.126H49.4985V133.189ZM39.4992 93.6886V88.7515H94.5011V98.6257H39.4992V93.6886ZM104.5 69V78.8742H29.5V108.5H94.5011V118.374H39.4992V148H104.5V78.8742H114.5V69H104.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 587 B

View File

Before

Width:  |  Height:  |  Size: 349 KiB

After

Width:  |  Height:  |  Size: 349 KiB

BIN
desktop/src-tauri/libcrypto-3-x64.dll vendored Normal file

Binary file not shown.

BIN
desktop/src-tauri/libssl-3-x64.dll vendored Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Some files were not shown because too many files have changed in this diff Show More