package server with client

This commit is contained in:
Bruce MacDonald 2023-06-23 18:38:22 -04:00
parent f0eee3faa0
commit c5bafaff54
8 changed files with 183 additions and 5 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
*.spec
*/build
*/dist
client/resources/server

126
client/package-lock.json generated
View file

@ -24,12 +24,15 @@
"@electron-forge/maker-zip": "^6.2.1",
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1",
"@electron-forge/plugin-webpack": "^6.2.1",
"@types/chmodr": "^1.0.0",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"@vercel/webpack-asset-relocator-loader": "^1.7.3",
"babel-loader": "^9.1.2",
"chmodr": "^1.2.0",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.8.1",
"electron": "25.2.0",
"eslint": "^8.43.0",
@ -2295,6 +2298,15 @@
"@types/responselike": "^1.0.0"
}
},
"node_modules/@types/chmodr": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/chmodr/-/chmodr-1.0.0.tgz",
"integrity": "sha512-S+X+Gy8V1uijitezjzXuan5vHbjllKgnC6q4VrD30HF2WRF6oIwQ/Wfjzvn5tGIIsl4VtRnBQbzqyzBo02juhw==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@ -3935,6 +3947,12 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chmodr": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.2.0.tgz",
"integrity": "sha512-Y5uI7Iq/Az6HgJEL6pdw7THVd7jbVOTPwsmcPOBjQL8e3N+pz872kzK5QxYGEy21iRys+iHWV0UZQXDFJo1hyA==",
"dev": true
},
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -4288,6 +4306,114 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
"node_modules/copy-webpack-plugin": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz",
"integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==",
"dev": true,
"dependencies": {
"fast-glob": "^3.2.11",
"glob-parent": "^6.0.1",
"globby": "^13.1.1",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0",
"serialize-javascript": "^6.0.0"
},
"engines": {
"node": ">= 14.15.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"webpack": "^5.1.0"
}
},
"node_modules/copy-webpack-plugin/node_modules/ajv": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
"integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/copy-webpack-plugin/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"ajv": "^8.8.2"
}
},
"node_modules/copy-webpack-plugin/node_modules/globby": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-13.2.0.tgz",
"integrity": "sha512-jWsQfayf13NvqKUIL3Ta+CIqMnvlaIDFveWE/dpOZ9+3AMEJozsxDvKA02zync9UuvOM8rOXzsD5GqKP4OnWPQ==",
"dev": true,
"dependencies": {
"dir-glob": "^3.0.1",
"fast-glob": "^3.2.11",
"ignore": "^5.2.0",
"merge2": "^1.4.1",
"slash": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/copy-webpack-plugin/node_modules/schema-utils": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
"integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
"ajv-formats": "^2.1.1",
"ajv-keywords": "^5.1.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/copy-webpack-plugin/node_modules/slash": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz",
"integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==",
"dev": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",

View file

@ -27,12 +27,15 @@
"@electron-forge/maker-zip": "^6.2.1",
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1",
"@electron-forge/plugin-webpack": "^6.2.1",
"@types/chmodr": "^1.0.0",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"@vercel/webpack-asset-relocator-loader": "^1.7.3",
"babel-loader": "^9.1.2",
"chmodr": "^1.2.0",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.8.1",
"electron": "25.2.0",
"eslint": "^8.43.0",

View file

@ -0,0 +1,24 @@
import chmodr from 'chmodr'
import * as path from 'path'
interface PluginOptions {
resourcePath: string
}
class PermissionsPlugin {
options: PluginOptions
constructor(options: PluginOptions) {
this.options = options
}
apply(compiler: any) {
compiler.hooks.afterEmit.tap('PermissionsPlugin', () => {
chmodr(path.join(this.options.resourcePath), 0o755, err => {
// this fails on the first call to suppress the error
})
})
}
}
export default PermissionsPlugin

View file

@ -1,4 +1,6 @@
import { app, BrowserWindow } from 'electron'
import { spawn } from 'child_process'
import * as path from 'path'
// This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Webpack
// plugin that tells the Electron app where to look for the Webpack-bundled app code (depending on
// whether you're running in development or production).
@ -24,6 +26,17 @@ const createWindow = (): void => {
transparent: true,
})
// Start the executable
let pyExecutable = path.join(__dirname, '../renderer/resources/server')
console.log(`Starting ${pyExecutable}`)
let pyProcess = spawn(pyExecutable)
pyProcess.stdout.on('data', data => {
console.log(`server: ${data}`)
})
pyProcess.stderr.on('data', data => {
console.error(`server: ${data}`)
})
// and load the index.html of the app.
mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY)

View file

@ -1,10 +1,19 @@
import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
import * as path from 'path'
import PermissionsPlugin from './permissions-plugin'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
export const plugins = [
new ForkTsCheckerWebpackPlugin({
logger: 'webpack-infrastructure',
}),
new CopyWebpackPlugin({
patterns: [{ from: 'resources', to: 'resources' }],
}),
new PermissionsPlugin({
resourcePath: '.webpack/renderer/resources/server',
}),
]

View file

@ -1,12 +1,12 @@
import site
import os
import shutil
from PyInstaller.__main__ import run as pyi_run
# Get the directory of site-packages and llama_cpp
# the llama_cpp directory is not included if not explicitly added
site_packages_dir = site.getsitepackages()[0]
llama_cpp_dir = os.path.join(site_packages_dir, "llama_cpp")
# Prepare the arguments for PyInstaller
args = [
"server.py",
"--paths",
@ -16,5 +16,7 @@ args = [
"--onefile",
]
# Generate the .spec file and run PyInstaller
# generate the .spec file and run PyInstaller
pyi_run(args)
shutil.copy2("dist/server", "../client/resources/server")

View file

@ -2,7 +2,7 @@ import json
import os
from llama_cpp import Llama
from flask import Flask, Response, stream_with_context, request
from flask_cors import CORS, cross_origin
from flask_cors import CORS
app = Flask(__name__)
CORS(app) # enable CORS for all routes