Skip to content

Commit

Permalink
add server project
Browse files Browse the repository at this point in the history
  • Loading branch information
StardustDL committed Mar 13, 2024
1 parent 3c68bf9 commit 4ba4658
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 38 deletions.
97 changes: 62 additions & 35 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,45 @@ jobs:
with:
name: self-results
path: ./self
web:
runs-on: ubuntu-latest
env:
PYTHONUTF8: 1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare Vite
run: |
cd ./src/web && npm install
- name: Set Server Build Env
shell: bash
run: |
echo -e "VITE_NOSERVER=0\nVITE_COMMIT_ID=${{ github.sha }}\nVITE_BUILD_DATE=$(date -Iseconds)" > ./src/web/.env
- name: Build Server
run: |
cd ./src/web && npm run build
- name: Upload server web results
uses: actions/upload-artifact@v4
with:
name: web-server-dist
path: ./src/web/dist
- name: Set Static Build Env
shell: bash
run: |
echo -e "VITE_NOSERVER=1\nVITE_COMMIT_ID=${{ github.sha }}\nVITE_BUILD_DATE=$(date -Iseconds)" > ./src/web/.env
- name: Build Static
run: |
cd ./src/web && npm run build
- name: Add track tag
run: |
python ./scripts/add_web_track.py
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: web-static-dist
path: ./src/web/dist
image:
needs: [web]
runs-on: ubuntu-latest
env:
PYTHONUTF8: 1
Expand All @@ -117,8 +155,15 @@ jobs:
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Inject Build Info
run: python ./scripts/inject_build.py
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: web-server-dist
path: ./src/web/dist
- name: Prepare
run: |
python ./scripts/inject_build.py
python ./scripts/docker_build.py
- name: Build
run: |
docker build -t aexpy/aexpy .
Expand Down Expand Up @@ -159,36 +204,14 @@ jobs:
shell: bash
run: |
cd cache && sudo find . -maxdepth 1 -type f -name "*.json" -exec docker run -v ${{ github.workspace }}/cache:/data -u "$(id -u):$(id -g)" aexpy/aexpy -vvv view /data/{} \;
- name: Test Server
run: |
docker run aexpy/aexpy -vvv serve --help
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: image-cache
path: ./cache
web:
runs-on: ubuntu-latest
env:
PYTHONUTF8: 1
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Prepare Vite
run: |
cd ./src/web && npm install
- name: Set Build Env
shell: bash
run: |
echo -e "VITE_NOSERVER=1\nVITE_COMMIT_ID=${{ github.sha }}\nVITE_BUILD_DATE=$(date -Iseconds)" > ./src/web/.env
- name: Build
run: |
cd ./src/web && npm run build
- name: Add track tag
run: |
python ./scripts/add_web_track.py
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: web-dist
path: ./src/web/dist
docs:
runs-on: ubuntu-latest
env:
Expand All @@ -211,15 +234,12 @@ jobs:
name: docs
path: ./docs/dist
deploy:
if: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && github.event_name == 'push' || github.event_name == 'release' }}
if: ${{ (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/v')) && github.event_name == 'push' || github.event_name == 'release' }}
needs: [image, docs, package, web]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
deploy-apis:
needs: [deploy]
if: ${{ github.event_name == 'push' }}
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
env:
PYTHONUTF8: 1
Expand Down Expand Up @@ -281,7 +301,7 @@ jobs:
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: web-dist
name: web-static-dist
path: ./web-dist
- name: Add redirects
shell: bash
Expand Down Expand Up @@ -332,8 +352,15 @@ jobs:
uses: docker/metadata-action@v5
with:
images: stardustdl/aexpy
- name: Inject Build Info
run: python ./scripts/inject_build.py
- name: Download app artifacts
uses: actions/download-artifact@v4
with:
name: web-server-dist
path: ./src/web/dist
- name: Prepare
run: |
python ./scripts/inject_build.py
python ./scripts/docker_build.py
- name: Deploy image
uses: docker/build-push-action@v5
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ results
logs
summary-logs
wwwroot
wwwdata
.idea
dist
pyenv
Expand Down
9 changes: 8 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# core dependencies
click==8.1.7
pydantic==2.6.4
mypy==1.9.0
mypy==1.9.0

# servers dependencies
Flask==3.0.2
tornado==6.4
Flask-Cors==4.0.0
Flask-Compress==1.14
29 changes: 29 additions & 0 deletions scripts/docker_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from datetime import datetime
import os
from pathlib import Path
import shutil
import subprocess

root = Path(__file__).parent.parent

mainSrc = root / "src" / "aexpy"
toolSrc = mainSrc / "tools"
serverSrc = root / "src" / "servers"

webDist = root / "src" / "web" / "dist"
serverWww = serverSrc / "wwwroot"


def frontend():
shutil.rmtree(serverWww)
shutil.copytree(webDist, serverWww)


def server():
target = toolSrc / "servers"
shutil.copytree(serverSrc, target)


if __name__ == "__main__":
frontend()
server()
33 changes: 33 additions & 0 deletions scripts/server_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from datetime import datetime
from pathlib import Path
import shutil
import subprocess

root = Path(__file__).parent.parent

webDist = root / "src" / "web" / "dist"
webEnv = root / "src" / "web" / ".env"
serverWww = root / "src" / "servers" / "wwwroot"


def build():
originalText = webEnv.read_text()
webEnv.write_text(
f"""
VITE_NOSERVER=0
VITE_COMMIT_ID=on-line
VITE_BUILD_DATE={datetime.now().isoformat()}
"""
)
subprocess.run("npm run build", shell=True, cwd=webDist.parent, check=True)
webEnv.write_text(originalText)


def copy():
shutil.rmtree(serverWww)
shutil.copytree(webDist, serverWww)


if __name__ == "__main__":
build()
copy()
13 changes: 13 additions & 0 deletions src/servers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import mimetypes

from flask import Flask
from flask_compress import Compress
from flask_cors import CORS

mimetypes.add_type("text/css", ".css")
mimetypes.add_type("text/javascript", ".js")
mimetypes.add_type("text/javascript", ".mjs")

app = Flask(__name__)
CORS(app)
Compress(app)
4 changes: 4 additions & 0 deletions src/servers/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .cli import serve as main

if __name__ == "__main__":
main()
37 changes: 37 additions & 0 deletions src/servers/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os
from pathlib import Path
from flask import Blueprint, Response, jsonify, request, send_file, send_from_directory

wwwdata = Path(__file__).parent.parent.joinpath("wwwdata")

if not wwwdata.is_dir():
os.makedirs(wwwdata, exist_ok=True)

api = Blueprint("api", __name__)


@api.route("/data/<path:path>", methods=["GET"])
def wwwrootFiles(path: str = "index.html"):
return send_from_directory(wwwdata, path)


@api.route("/tasks/extract", methods=["POST"])
def extract():
return ""


@api.route("/tasks/diff", methods=["POST"])
def diff():
return ""


@api.route("/info", methods=["GET"])
def info():
from aexpy import COMMIT_ID, BUILD_DATE

return jsonify(
{
"commitId": COMMIT_ID,
"buildDate": BUILD_DATE.isoformat(),
}
)
11 changes: 11 additions & 0 deletions src/servers/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import click


@click.command()
@click.option("-d", "--debug", is_flag=True, help="Debug mode.")
@click.option("-p", "--port", type=int, default=8008, help="Port to listen on.")
def serve(debug: "bool" = False, port: "int" = 8008):
"""Serve web server."""
from .entrypoint import serve as inner, buildApp

inner(buildApp(), debug, port)
34 changes: 34 additions & 0 deletions src/servers/entrypoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import os
import pathlib
import shutil

import click
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
from flask import Flask


def buildApp():
from . import app
from .api import api
from .frontend import frontend

app.register_blueprint(api, url_prefix="/api")
app.register_blueprint(frontend, url_prefix="/")

return app


def serve(app: Flask, debug: bool = False, port: int = 8008):
if debug:
app.run(host="0.0.0.0", port=port, debug=debug)

else:
click.echo(f"Listening on port {port}...")
click.echo(f"Visit http://localhost:{port} to AexPy.")

container = tornado.wsgi.WSGIContainer(app)
http_server = tornado.httpserver.HTTPServer(container)
http_server.listen(port)
tornado.ioloop.IOLoop.current().start()
18 changes: 18 additions & 0 deletions src/servers/frontend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pathlib

from flask import Blueprint, send_file, send_from_directory

wwwroot = pathlib.Path(__file__).parent.joinpath("wwwroot")

frontend = Blueprint("frontend", __name__)


@frontend.route("/", methods=["GET"])
@frontend.route("/<path:path>", methods=["GET"])
def wwwrootFiles(path: str = "index.html"):
return send_from_directory(wwwroot, path)


@frontend.errorhandler(404)
def pageNotFound(error):
return send_file(wwwroot.joinpath("index.html"))
2 changes: 1 addition & 1 deletion src/web/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "aexpy-web",
"private": true,
"version": "0.3.0",
"version": "0.4.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
3 changes: 2 additions & 1 deletion src/web/src/services/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export interface State {

export const key: InjectionKey<Store<State>> = Symbol()

const defaultApiUrl = import.meta.env.DEV ? "http://localhost:8008/api" : "https://stardustdl-labs.github.io/aexpy-index";
const defaultApiUrl = import.meta.env.DEV ? "http://localhost:8008/api" :
(import.meta.env.VITE_NOSERVER ? "https://stardustdl-labs.github.io/aexpy-index" : "/api");

export const store = createStore<State>({
state() {
Expand Down

0 comments on commit 4ba4658

Please sign in to comment.