Skip to content

Commit

Permalink
feat: new web UI [skip ci] (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
kharkevich authored Apr 3, 2024
1 parent a0d624b commit 4ff4dc2
Show file tree
Hide file tree
Showing 106 changed files with 8,719 additions and 145 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/bandit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ on:
- synchronize

jobs:
main:
name: Run bandit
runs-on: ubuntu-latest
steps:
- uses: mdegis/[email protected]
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
path: "."
level: high
confidence: high
exit_zero: true
main:
name: Run bandit
runs-on: ubuntu-latest
steps:
- uses: mdegis/[email protected]
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
path: "."
level: high
confidence: high
exit_zero: true
10 changes: 5 additions & 5 deletions .github/workflows/commit-message-check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Conventional commit message checker'
name: "Conventional commit message checker"
on:
pull_request:
types:
Expand All @@ -17,7 +17,7 @@ jobs:
with:
pattern: '^(|feat|fix|chore|docs|style|ci|refactor|perf|test)(\([\w-]+\))?:\s.+$|^(Merge\sbranch)'
error: 'Your first line has to contain a commit type like "feat|fix|chore|docs|style|ci|refactor|perf|test".'
excludeDescription: 'true' # optional: this excludes the description body of a pull request
excludeTitle: 'true' # optional: this excludes the title of a pull request
checkAllCommitMessages: 'true' # optional: this checks all commits associated with a pull request
accessToken: ${{ secrets.GITHUB_TOKEN }} # github access token is only required if checkAllCommitMessages is true
excludeDescription: "true"
excludeTitle: "true"
checkAllCommitMessages: "true"
accessToken: ${{ secrets.GITHUB_TOKEN }}
51 changes: 25 additions & 26 deletions .github/workflows/pr-validate-title.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,29 @@ on:
- edited
- synchronize


jobs:
main:
name: Conventional commit title validation
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
fix
feat
docs
ci
chore
build
test
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
headerPattern: '^(\w*)(?:\(([\w$.\-*/ ]*)\))?: (.*)$'
headerPatternCorrespondence: type, scope, subject
wip: true
main:
name: Conventional commit title validation
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
fix
feat
docs
ci
chore
build
test
requireScope: false
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
doesn't start with an uppercase character.
headerPattern: '^(\w*)(?:\(([\w$.\-*/ ]*)\))?: (.*)$'
headerPatternCorrespondence: type, scope, subject
wip: true
34 changes: 34 additions & 0 deletions .github/workflows/pypi-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Pre Release
on:
push:
branches:
- pre-release
jobs:
pypi-publish:
name: upload release to PyPI Test
runs-on: ubuntu-latest
environment: PyPI Test
permissions:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Make release
uses: cycjimmy/semantic-release-action@v4
with:
extra_plugins: |
- @semantic-release/exec
env:
GIT_USER: ${{ secrets.GITHUB_TOKEN }}
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
32 changes: 32 additions & 0 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Release
on:
push:
branches:
- main
jobs:
pypi-publish:
name: upload release to PyPI
runs-on: ubuntu-latest
environment: PyPI
permissions:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Make release
uses: cycjimmy/semantic-release-action@v4
with:
extra_plugins: |
- @semantic-release/exec
env:
GIT_USER: ${{ secrets.GITHUB_TOKEN }}
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/venv/
/instance/
/mlruns/
mlruns/
basic_auth.db
basic_auth
# Byte-compiled / optimized / DLL files
Expand Down Expand Up @@ -169,3 +169,7 @@ flask_session/
*.db
*.sqlite3
*.sqlite

node_modules/
.angular/
mlflow_oidc_auth/ui
36 changes: 36 additions & 0 deletions .releaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"branches": [
{
"name": "main"
},
{
"name": "pre-release",
"channel": "prerelease",
"prerelease": true
}
],
"ci": true,
"dryRun": false,
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
[
"@semantic-release/exec",
{
"prepareCmd": "./scripts/release.sh ${nextRelease.version}"
}
],
[
"@semantic-release/github",
{
"assets": [
{
"path": "dist/*.whl"
}
],
"successComment": true,
"addReleases": "top"
}
]
]
}
5 changes: 5 additions & 0 deletions mlflow_oidc_auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import os

version = os.environ.get("MLFLOW_OIDC_AUTH_VERSION", "0.0.2.dev0")

__version__ = version
2 changes: 2 additions & 0 deletions mlflow_oidc_auth/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
rule=routes.CALLBACK, methods=["GET", "POST"], view_func=views.callback
)
app.add_url_rule(rule=routes.STATIC, methods=["GET"], view_func=views.oidc_static)
app.add_url_rule(rule=routes.UI, methods=["GET"], view_func=views.oidc_ui)
app.add_url_rule(rule=routes.UI_ROOT, methods=["GET"], view_func=views.oidc_ui)
app.add_url_rule(rule=routes.OIDC_HOME, methods=["GET"], view_func=views.oidc_home)
app.add_url_rule(
rule=routes.SEARCH_MODEL, methods=["GET"], view_func=views.search_model
Expand Down
2 changes: 2 additions & 0 deletions mlflow_oidc_auth/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
CALLBACK = "/callback"

STATIC = "/oidc/static/<path:filename>"
UI = "/oidc/ui/<path:filename>"
UI_ROOT = "/oidc/ui/"
PERMISSIONS = "/oidc/permissions"
PERMISSIONS_USERS = "/oidc/permissions/users"
PERMISSIONS_EXPERIMENTS = "/oidc/permissions/experiments"
Expand Down
11 changes: 10 additions & 1 deletion mlflow_oidc_auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def _get_request_param(param: str) -> str:

def _is_unprotected_route(path: str) -> bool:
return path.startswith(
("/static", "/favicon.ico", "/health", "/login", "/callback", "/oidc/static")
("/static", "/favicon.ico", "/health", "/login", "/callback", "/oidc/static", "/oidc/ui")
)


Expand Down Expand Up @@ -306,6 +306,15 @@ def oidc_static(filename):
# Return the file from the specified directory
return send_from_directory(static_directory, filename)

def oidc_ui(filename=None):
# Specify the directory where your static files are located
ui_directory = os.path.join(os.path.dirname(__file__), "ui")
print(filename)
if not filename:
filename = "index.html"
elif not os.path.exists(os.path.join(ui_directory, filename)):
filename = "index.html"
return send_from_directory(ui_directory, filename)

# TODO
def search_model():
Expand Down
110 changes: 9 additions & 101 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "mlflow-oidc-auth"
version = "0.0.1.dev0"
dynamic = ["version"]
description = "OIDC auth plugin for MLflow"
readme = "README.md"
keywords = ["mlflow", "oauth2", "oidc"]
Expand Down Expand Up @@ -52,109 +52,17 @@ oidc-auth = "mlflow_oidc_auth.app:app"
basic-auth = "mlflow_oidc_auth.client:AuthServiceClient"

[tool.setuptools.package-data]
mlflow_oidc_auth = ["db/migrations/alembic.ini", "templates/*", "static/*"]
mlflow_oidc_auth = [
"db/migrations/alembic.ini",
"templates/*",
"static/*",
"ui/*",
]

[tool.setuptools.packages.find]
where = ["."]
include = ["mlflow_oidc_auth", "mlflow_oidc_auth.*"]
exclude = ["tests", "tests.*"]


[tool.ruff]
line-length = 100
target-version = "py38"
force-exclude = true
extend-include = ["*.ipynb"]
extend-exclude = [
"tests/protos",
]

[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = 88

[tool.ruff.lint]
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
select = [
"B006", # multiple-argument-default
"B015", # useless-comparison
"D209", # new-line-after-last-paragraph
"E", # error
"F", # Pyflakes
"C4", # flake8-comprehensions
"I", # isort
"PLR0402", # manual-from-import
"PT001", # pytest-fixture-incorrect-parentheses-style
"PT002", # pytest-fixture-positional-args
"PT003", # pytest-extraneous-scope-function
"PT006", # pytest-parameterize-names-wrong-type
"PT007", # pytest-parameterize-values-wrong-type
"PT009", # pytest-unittest-assertion
"PT010", # pytest-raises-without-exception
"PT011", # pytest-raises-too-broad
"PT012", # pytest-raises-with-multiple-statements
"PT013", # pytest-incorrect-pytest-import
"PT014", # pytest-duplicate-parametrize-test-cases
"PT018", # pytest-composite-assertion
"PT022", # pytest-useless-yield-fixture
"PT023", # pytest-incorrect-mark-parentheses-style
"PT026", # pytest-use-fixtures-without-parameters
"PT027", # pytest-unittest-raises-assertion
"RET504", # unnecessary-assign
"RUF010", # explicit-f-string-type-conversion
"RUF013", # implicit-optional
"RUF100", # unused-noqa
"S307", # suspicious-eval-usage
"S324", # hashlib-insecure-hash-function
"SIM101", # duplicate-isinstance-call
"SIM103", # needless-bool
"SIM108", # if-else-block-instead-of-if-exp
"SIM114", # if-with-same-arms
"SIM115", # open-file-with-context-handler
"SIM210", # if-expr-with-true-false
"SIM910", # dict-get-with-none-default
"T20", # flake8-print
"TID251", # banned-api
"TID252", # relative-improt
"TRY302", # useless-try-except
"UP004", # useless-object-inheritance
"UP008", # super-call-with-parameters
"UP011", # lru-cache-without-parameters
"UP012", # unecessary-encode-utf8
"UP015", # redundant-open-modes
"UP030", # format-literals
"UP031", # printf-string-format
"UP032", # f-string
"UP034", # extraneous-parenthesis
"W", # warning
]
ignore = [
# "E402", # module-import-not-at-top-of-file
"E721", # type-comparison
"E741", # ambiguous-variable-name
"F811", # redefined-while-unused
]

[tool.ruff.lint.per-file-ignores]
"docs/*" = ["T20", "RET504", "E501"]
"mlflow/*" = ["PT018"]

[tool.ruff.lint.flake8-pytest-style]
mark-parentheses = false
fixture-parentheses = false
raises-require-match-for = ["*"]

[tool.ruff.lint.flake8-tidy-imports]
ban-relative-imports = "all"

[tool.ruff.lint.isort]
forced-separate = ["tests"]

[tool.ruff.lint.flake8-tidy-imports.banned-api]
"pkg_resources".msg = "We're migrating away from pkg_resources. Please use importlib.resources or importlib.metadata instead."

[tool.clint]
exclude = [
"docs",
"tests/protos",
]
[tool.setuptools.dynamic]
version = {attr = "mlflow_oidc_auth.version"}
Loading

0 comments on commit 4ff4dc2

Please sign in to comment.