diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index dedba931e..b9b8f06ec 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,20 +1,26 @@ -# [Choice] Go version (use -bullseye variants on local arm64/Apple Silicon): 1, 1.18, 1.17, 1-bullseye, 1.18-bullseye, 1.17-bullseye, 1-buster, 1.18-buster, 1.17-buster -ARG VARIANT=1-bullseye -FROM mcr.microsoft.com/devcontainers/go:0-${VARIANT} - -# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 -ARG NODE_VERSION="none" -RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi +# [Choice] Go version (use -bookworm, or -bullseye variants on local arm64/Apple Silicon): 1, 1.21, 1.20, 1-bookworm, 1.21-bookworm, 1.20-bookworm, 1-bullseye, 1.21-bullseye, 1.20-bullseye +ARG VARIANT=1-bookworm +FROM mcr.microsoft.com/devcontainers/go:1-${VARIANT} # [Optional] Uncomment this section to install additional OS packages. -RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install --no-install-recommends libssl-dev postgresql-client python-is-python3 python3-pip python3-dev python3-venv sqlite3 emacs-nox ripgrep fzf \ - && pip install pipenv +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends \ + emacs-nox \ + fzf \ + libssl-dev \ + pipenv \ + postgresql-client \ + python-is-python3 \ + python3-dev \ + python3-pip \ + python3-venv \ + ripgrep \ + sqlite3 # [Optional] Uncomment the next lines to use go get to install anything else you need USER vscode -RUN go install github.com/vektra/mockery/v2@v2.30.16 \ - && go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.3 \ +RUN go install github.com/vektra/mockery/v2@v2.32.4 \ + && go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.1 \ && go install golang.org/x/tools/cmd/goimports@v0.11.0 \ && go install mvdan.cc/gofumpt@v0.5.0 USER root @@ -23,4 +29,8 @@ USER root # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 # Install xh -RUN curl -sfL https://raw.githubusercontent.com/ducaale/xh/master/install.sh | XH_BINDIR=/usr/local/bin sh \ No newline at end of file +RUN curl -sfL https://raw.githubusercontent.com/ducaale/xh/master/install.sh | XH_BINDIR=/usr/local/bin sh + +# Add docker-compose symlink to Docker Compose v2 +# This is a workaround until https://github.com/devcontainers/features/pull/621 lands +RUN ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/ \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9f186d622..998b4d74c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -22,7 +22,9 @@ "golang.Go", "ms-python.python", "pbkit.vscode-pbkit", - "redhat.vscode-yaml" + "redhat.vscode-yaml", + "ms-python.black-formatter", + "ms-python.isort" ] } }, @@ -38,10 +40,13 @@ "remoteUser": "vscode", "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { - "dockerDashComposeVersion": "v2" + "dockerDashComposeVersion": "none" }, "ghcr.io/devcontainers/features/git:1": {}, "ghcr.io/devcontainers/features/github-cli:1": {}, + "ghcr.io/devcontainers/features/node:1": { + "version": "16" + }, "ghcr.io/dhoeric/features/k6:1": {}, "ghcr.io/christophermacgown/devcontainer-features/minio-client:1": {} }, diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 91e377da1..26f645b19 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -15,9 +15,7 @@ services: # [Choice] Go version 1, 1.18, 1.17 # Append -bullseye or -buster to pin to an OS version. # Use -bullseye variants on local arm64/Apple Silicon. - VARIANT: 1.20-bullseye - # Options - NODE_VERSION: "16" + VARIANT: 1.21-bookworm env_file: # Ensure that the variables in .env match the same variables in devcontainer.json - .env diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1577c4fe8..01d8db114 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,9 @@ permissions: contents: read jobs: - lint: + go-lint: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id - name: Lint + name: Go Lint runs-on: ubuntu-latest steps: - name: Checkout @@ -23,7 +23,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21" - name: Read build tags id: tags @@ -48,7 +48,7 @@ jobs: fi - name: Download mockery - run: go install github.com/vektra/mockery/v2@v2.30.16 + run: go install github.com/vektra/mockery/v2@v2.32.4 - name: Generate mocks run: make mocks-generate @@ -61,9 +61,28 @@ jobs: version: "2022.1.3" build-tags: ${{ steps.tags.outputs.tags }} - golang-unit-tests: + python-lint: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id - name: Golang Unit Tests + name: Python Lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install pipenv + run: pip install pipenv==2022.12.19 + + - name: Run Python linters + run: make python-lint + + go-unit-tests: + if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id + name: Go Unit Tests runs-on: ubuntu-latest steps: - name: Checkout @@ -72,20 +91,20 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21" - name: Download mockery - run: go install github.com/vektra/mockery/v2@v2.30.16 + run: go install github.com/vektra/mockery/v2@v2.32.4 - name: Generate mocks run: make mocks-generate - - name: Run Golang Unit Tests + - name: Run Go Unit Tests run: make test-go-unit - golang-integration-tests: + go-integration-tests: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id - name: Golang Integration Tests + name: Go Integration Tests runs-on: ubuntu-latest steps: - name: Checkout @@ -97,12 +116,19 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21" - - name: Run Integration Tests + - name: Run Integration Tests (Sqlite) run: make service-test env: DOCKER_BUILDKIT: 1 + FML_DATABASE_URI: sqlite://fasttrack-test.db + + - name: Run Integration Tests (Postgres) + run: make service-test + env: + DOCKER_BUILDKIT: 1 + FML_DATABASE_URI: postgres://postgres:postgres@postgres/postgres python-integration-tests: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id @@ -133,14 +159,14 @@ jobs: - name: Setup Go uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21" - name: Run ${{ matrix.api }} integration tests run: ./tests/integration/python/${{ matrix.api }}/test.sh - golang-build: + build: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id - name: Build Go binary for ${{ matrix.os }}/${{ matrix.arch }} + name: Build software distribution for ${{ matrix.os }}/${{ matrix.arch }} strategy: matrix: os: [darwin, linux, windows] @@ -164,6 +190,19 @@ jobs: with: fetch-depth: 0 + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: "1.21" + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: "3.11" + + - name: Install pipenv + run: pip install pipenv==2022.12.19 + - name: Install arm64 cross-compilation toolchain on Linux if: matrix.os == 'linux' && matrix.arch == 'arm64' run: | @@ -178,18 +217,24 @@ jobs: sudo apt-get install -y --no-install-recommends gcc-mingw-w64-x86-64-win32 echo CC=x86_64-w64-mingw32-gcc >> $GITHUB_ENV - - name: Build and archive Go binary - run: make go-dist + - name: Build software distribution + run: make dist env: GOOS: ${{ matrix.os }} GOARCH: ${{ matrix.arch }} - - name: Upload artifact + - name: Upload binary artifact uses: actions/upload-artifact@v3 with: name: fasttrackml-archives path: dist/* + - name: Upload wheels artifact + uses: actions/upload-artifact@v3 + with: + name: fasttrackml-wheels + path: wheelhouse/*.whl + build-image: if: github.event_name == 'schedule' || github.event_name == 'push' || github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id name: Build container image @@ -250,11 +295,12 @@ jobs: all-required-checks-done: name: All required checks done needs: - - lint - - golang-unit-tests - - golang-integration-tests + - go-lint + - python-lint + - go-unit-tests + - go-integration-tests - python-integration-tests - - golang-build + - build - build-image runs-on: ubuntu-latest steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 061b404b6..e3a17e329 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,6 +49,24 @@ jobs: exit 1 fi + pypi-publish: + name: upload release to PyPI + needs: validate + if: github.event.workflow_run.head_branch != 'main' + runs-on: ubuntu-latest + environment: release + permissions: + id-token: write + steps: + - name: Download artifact + run: gh run download ${{ github.event.workflow_run.id }} --repo ${{ github.event.workflow_run.repository.full_name }} --name fasttrackml-wheels --dir wheelhouse + env: + GH_TOKEN: ${{ github.token }} + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: wheelhouse/ + github-release: name: Publish GitHub release needs: validate diff --git a/.gitignore b/.gitignore index 8e4b39f23..98c1996fa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .idea # Binaries +dist/ fml fasttrackml *.exe @@ -25,4 +26,9 @@ mock_* # Optional workspace go.work -*.code-workspace \ No newline at end of file +*.code-workspace + +# Python wheels +python/build/ +python/*.egg-info/ +wheelhouse/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 39dca7053..23f289b1d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,19 @@ "go.lintTool": "golangci-lint", "go.lintFlags": [ "--fast" + ], + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter", + "editor.codeActionsOnSave": { + "source.organizeImports": true + } + }, + "black-formatter.args": [ + "--line-length", + "120" + ], + "isort.args": [ + "--profile", + "black" ] } \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index bbcb7338a..3b46e1e51 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build fml binary -FROM --platform=$BUILDPLATFORM golang:1.20 AS go-build +FROM --platform=$BUILDPLATFORM golang:1.21 AS go-build ARG TARGETARCH RUN bash -c "\ diff --git a/Makefile b/Makefile index 06c533913..19022753b 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,9 @@ endif ARCHIVE_NAME=dist/fasttrackml_$(shell go env GOOS | sed s/darwin/macos/)_$(shell go env GOARCH | sed s/amd64/x86_64/).$(ARCHIVE_EXT) ARCHIVE_FILES=$(APP) LICENSE README.md +ifeq ($(FML_DATABASE_URI),) + FML_DATABASE_URI := "sqlite://fasttrackml.db" +endif # # Default target (help) # @@ -81,6 +84,31 @@ go-dist: go-build ## archive app binary. @if [ -f $(ARCHIVE_NAME) ]; then rm -f $(ARCHIVE_NAME); fi @$(ARCHIVE_CMD) $(ARCHIVE_NAME) $(ARCHIVE_FILES) +# +# Python targets. +# +.PHONY: python-env +python-env: ## create python virtual environment. + @echo '>>> Creating python virtual environment.' + @pipenv sync + +.PHONY: python-dist +python-dist: go-build python-env ## build python wheels. + @echo '>>> Building Python Wheels.' + @VERSION=$(VERSION) pipenv run python3 -m pip wheel ./python --wheel-dir=wheelhouse --no-deps + +.PHONY: python-format +python-format: python-env ## format python code. + @echo '>>> Formatting python code.' + @pipenv run black --line-length 120 . + @pipenv run isort --profile black . + +.PHONY: python-lint +python-lint: python-env ## check python code formatting. + @echo '>>> Checking python code formatting.' + @pipenv run black --check --line-length 120 . + @pipenv run isort --check-only --profile black . + # # Tests targets. # @@ -127,7 +155,7 @@ service-start: service-build service-start-dependencies ## start service in dock @sleep 5 @echo ">>> Starting service." @echo ">>> Starting up service container." - @docker-compose up -d service + @docker-compose up -e FML_DATABASE_URI -d service .PHONY: service-stop service-stop: ## stop service in docker. @@ -141,7 +169,7 @@ service-restart: service-stop service-start ## restart service in docker service-test: service-stop service-start ## run tests over the service in docker. @echo ">>> Running tests over service." @docker-compose \ - run integration-tests + run -e FML_DATABASE_URI integration-tests .PHONY: service-clean service-clean: ## clean service in docker. @@ -171,7 +199,10 @@ PHONY: build build: go-build ## build the go components PHONY: dist -dist: go-dist ## archive the go components +dist: go-dist python-dist ## build the software archives + +PHONY: format +format: go-format python-format ## format the code PHONY: run run: build ## run the FastTrackML server diff --git a/Pipfile b/Pipfile new file mode 100644 index 000000000..9bfaaeff5 --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +mlflow-skinny = "==2.6.0" +black = "*" +isort = "*" + +[dev-packages] + +[requires] +python_version = "3.11" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 000000000..b2541ba2c --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,393 @@ +{ + "_meta": { + "hash": { + "sha256": "67894a1e589c0c72158837827f8ca8b0dfa33c0f04f7126f1d6e44a472357f20" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "black": { + "hashes": [ + "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3", + "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb", + "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087", + "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320", + "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6", + "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3", + "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc", + "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f", + "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587", + "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91", + "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a", + "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad", + "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926", + "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9", + "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be", + "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd", + "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96", + "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491", + "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2", + "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a", + "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f", + "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995" + ], + "index": "pypi", + "version": "==23.7.0" + }, + "certifi": { + "hashes": [ + "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", + "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.7.22" + }, + "charset-normalizer": { + "hashes": [ + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" + }, + "click": { + "hashes": [ + "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd", + "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.6" + }, + "cloudpickle": { + "hashes": [ + "sha256:61f594d1f4c295fa5cd9014ceb3a1fc4a70b0de1164b94fbc2d854ccba056f9f", + "sha256:d89684b8de9e34a2a43b3460fbca07d09d6e25ce858df4d5a44240403b6178f5" + ], + "markers": "python_version >= '3.6'", + "version": "==2.2.1" + }, + "databricks-cli": { + "hashes": [ + "sha256:5a545063449f3b9ad904644c0f251058485e29e564dedf8d4e4a7b45caf9549b", + "sha256:5b025943c70bbd374415264d38bfaddfb34ce070fadb083d851aec311e0f8901" + ], + "version": "==0.17.7" + }, + "entrypoints": { + "hashes": [ + "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4", + "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f" + ], + "markers": "python_version >= '3.6'", + "version": "==0.4" + }, + "gitdb": { + "hashes": [ + "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a", + "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7" + ], + "markers": "python_version >= '3.7'", + "version": "==4.0.10" + }, + "gitpython": { + "hashes": [ + "sha256:8d9b8cb1e80b9735e8717c9362079d3ce4c6e5ddeebedd0361b228c3a67a62f6", + "sha256:e3d59b1c2c6ebb9dfa7a184daf3b6dd4914237e7488a1730a6d8f6f5d0b4187f" + ], + "markers": "python_version >= '3.7'", + "version": "==3.1.32" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "importlib-metadata": { + "hashes": [ + "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" + ], + "markers": "python_version >= '3.8'", + "version": "==6.8.0" + }, + "isort": { + "hashes": [ + "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504", + "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6" + ], + "index": "pypi", + "version": "==5.12.0" + }, + "mlflow-skinny": { + "hashes": [ + "sha256:b63c6555645af0196b3c92da849968189dfd72d2c1397f7b149593db6b404d66", + "sha256:c1a71bc4abb83169d4cff012c1c050c203775d4a7462d059c4523a481f0a9688" + ], + "index": "pypi", + "version": "==2.6.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", + "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.0" + }, + "oauthlib": { + "hashes": [ + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.2" + }, + "packaging": { + "hashes": [ + "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1" + }, + "pathspec": { + "hashes": [ + "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", + "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" + ], + "markers": "python_version >= '3.7'", + "version": "==0.11.2" + }, + "platformdirs": { + "hashes": [ + "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d", + "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d" + ], + "markers": "python_version >= '3.7'", + "version": "==3.10.0" + }, + "protobuf": { + "hashes": [ + "sha256:44825e963008f8ea0d26c51911c30d3e82e122997c3c4568fd0385dd7bacaedf", + "sha256:567fe6b0647494845d0849e3d5b260bfdd75692bf452cdc9cb660d12457c055d", + "sha256:5ab19ee50037d4b663c02218a811a5e1e7bb30940c79aac385b96e7a4f9daa61", + "sha256:5d0ceb9de6e08311832169e601d1fc71bd8e8c779f3ee38a97a78554945ecb85", + "sha256:6c817cf4a26334625a1904b38523d1b343ff8b637d75d2c8790189a4064e51c3", + "sha256:81cb9c4621d2abfe181154354f63af1c41b00a4882fb230b4425cbaed65e8f52", + "sha256:82e6e9ebdd15b8200e8423676eab38b774624d6a1ad696a60d86a2ac93f18201", + "sha256:8bb52a2be32db82ddc623aefcedfe1e0eb51da60e18fcc908fb8885c81d72109", + "sha256:a38400a692fd0c6944c3c58837d112f135eb1ed6cdad5ca6c5763336e74f1a04", + "sha256:a6b1ca92ccabfd9903c0c7dde8876221dc7d8d87ad5c42e095cc11b15d3569c7", + "sha256:ae7a1835721086013de193311df858bc12cd247abe4ef9710b715d930b95b33e", + "sha256:ae97b5de10f25b7a443b40427033e545a32b0e9dda17bcd8330d70033379b3e5", + "sha256:e8834ef0b4c88666ebb7c7ec18045aa0f4325481d724daa624a4cf9f28134653" + ], + "markers": "python_version >= '3.7'", + "version": "==4.24.0" + }, + "pyjwt": { + "hashes": [ + "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de", + "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320" + ], + "markers": "python_version >= '3.7'", + "version": "==2.8.0" + }, + "pytz": { + "hashes": [ + "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588", + "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb" + ], + "version": "==2023.3" + }, + "pyyaml": { + "hashes": [ + "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", + "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", + "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", + "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", + "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", + "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", + "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", + "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", + "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", + "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", + "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", + "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", + "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", + "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", + "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", + "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", + "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", + "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", + "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", + "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", + "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", + "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", + "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", + "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", + "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", + "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", + "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", + "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", + "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", + "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", + "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", + "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", + "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", + "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", + "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", + "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", + "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", + "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", + "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" + ], + "markers": "python_version >= '3.6'", + "version": "==6.0.1" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "smmap": { + "hashes": [ + "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94", + "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936" + ], + "markers": "python_version >= '3.6'", + "version": "==5.0.0" + }, + "sqlparse": { + "hashes": [ + "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", + "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" + ], + "markers": "python_version >= '3.5'", + "version": "==0.4.4" + }, + "tabulate": { + "hashes": [ + "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", + "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f" + ], + "markers": "python_version >= '3.7'", + "version": "==0.9.0" + }, + "urllib3": { + "hashes": [ + "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f", + "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.16" + }, + "zipp": { + "hashes": [ + "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", + "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" + ], + "markers": "python_version >= '3.8'", + "version": "==3.16.2" + } + }, + "develop": {} +} diff --git a/docker-compose.yml b/docker-compose.yml index 1d9742305..e4a967d9f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: MINIO_CONSOLE_ADDRESS: ":9001" integration-tests: - image: golang:1.20 + image: golang:1.21 command: make test-go-integration volumes: - .:/go/src diff --git a/docs/example/random_forest.py b/docs/example/random_forest.py index 08958050a..ce89cc225 100644 --- a/docs/example/random_forest.py +++ b/docs/example/random_forest.py @@ -1,9 +1,8 @@ +import mlflow import pandas as pd from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split -import mlflow - ALL_FILES = ["data/0.csv", "data/1.csv", "data/2.csv", "data/3.csv"] mlflow.set_tracking_uri("http://localhost:5000") @@ -28,9 +27,7 @@ def read_data(): X = data_df.iloc[:, :-1].values Y = data_df.iloc[:, -1].values # Random State is set to 42 for reproducibility - Xtrain, Xtest, Ytrain, Ytest = train_test_split( - X, Y, test_size=0.50, random_state=42 - ) + Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, Y, test_size=0.50, random_state=42) print("Completed Data Read") return data_df, Xtrain, Xtest, Ytrain, Ytest diff --git a/go.mod b/go.mod index e14b13016..0fa95118f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/G-Research/fasttrackml -go 1.18 +go 1.21 replace ( github.com/mattn/go-sqlite3 v1.14.16 => github.com/jgiannuzzi/go-sqlite3 v1.14.17-0.20230327164124-765f25ea5431 diff --git a/go.sum b/go.sum index 1d2dfef54..1ce25d4dc 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,7 @@ github.com/G-Research/fasttrackml-ui-aim v0.31602.7/go.mod h1:R8eNxWoWxiQ4vXOwkf github.com/G-Research/fasttrackml-ui-mlflow v0.20301.1 h1:yDVHbMx0Y8GFZq0D0STnlmIYDIk4phGKCvVIKrlNn00= github.com/G-Research/fasttrackml-ui-mlflow v0.20301.1/go.mod h1:0NZjizx6aygBaV8uQ81oCTMVekOFTh6ZDTqTAE6NYdc= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= +github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apache/arrow/go/v12 v12.0.1 h1:JsR2+hzYYjgSUkBSaahpqCetqZMr76djX80fF/DiJbg= @@ -106,6 +107,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -162,6 +164,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -223,9 +226,11 @@ github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -257,6 +262,7 @@ github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rotisserie/eris v0.5.4 h1:Il6IvLdAapsMhvuOahHWiBnl1G++Q0/L5UIkI5mARSk= github.com/rotisserie/eris v0.5.4/go.mod h1:Z/kgYTJiJtocxCbFfvRmO+QejApzG6zpyky9G1A4g9s= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -301,6 +307,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -407,6 +414,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -519,6 +527,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E= +gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -610,6 +619,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/pkg/api/mlflow/service/artifact/service_test.go b/pkg/api/mlflow/service/artifact/service_test.go index 28bdc4fcb..f9c4707f5 100644 --- a/pkg/api/mlflow/service/artifact/service_test.go +++ b/pkg/api/mlflow/service/artifact/service_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/G-Research/fasttrackml/pkg/api/mlflow/api" "github.com/G-Research/fasttrackml/pkg/api/mlflow/api/request" @@ -39,7 +38,7 @@ func TestService_ListArtifacts_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "id", ).Return(&models.Run{ ID: "id", @@ -113,7 +112,7 @@ func TestService_ListArtifacts_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "id", ).Return(nil, errors.New("database error")) return NewService( @@ -139,7 +138,7 @@ func TestService_ListArtifacts_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "id", ).Return(&models.Run{ ID: "id", diff --git a/pkg/api/mlflow/service/experiment/service_test.go b/pkg/api/mlflow/service/experiment/service_test.go index f349a8417..70c41cd65 100644 --- a/pkg/api/mlflow/service/experiment/service_test.go +++ b/pkg/api/mlflow/service/experiment/service_test.go @@ -21,10 +21,10 @@ func TestService_CreateExperiment_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, nil) experimentRepository.On( - "Create", mock.AnythingOfType("*context.emptyCtx"), mock.Anything, + "Create", context.TODO(), mock.Anything, ).Return(nil) // call service under testing. @@ -90,7 +90,7 @@ func TestService_CreateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, nil) return NewService( &config.ServiceConfig{}, @@ -108,7 +108,7 @@ func TestService_CreateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -126,7 +126,7 @@ func TestService_CreateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(&models.Experiment{}, nil) return NewService( &config.ServiceConfig{}, @@ -144,10 +144,10 @@ func TestService_CreateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, nil) experimentRepository.On( - "Create", mock.AnythingOfType("*context.emptyCtx"), mock.Anything, + "Create", context.TODO(), mock.Anything, ).Return(errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -165,18 +165,18 @@ func TestService_CreateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, nil) experimentRepository.On( "Create", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(experiment *models.Experiment) bool { experiment.ID = common.GetPointer(int32(1)) return true }), ).Return(nil) experimentRepository.On( - "Update", mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("*models.Experiment"), + "Update", context.TODO(), mock.AnythingOfType("*models.Experiment"), ).Return(errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -200,13 +200,13 @@ func TestService_DeleteExperiment_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( "Update", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(experiment *models.Experiment) bool { assert.Equal(t, experiment.LifecycleStage, models.LifecycleStageDeleted) assert.NotNil(t, experiment.LastUpdateTime) @@ -272,7 +272,7 @@ func TestService_DeleteExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(nil, errors.New("experiment not found")) return NewService( &config.ServiceConfig{}, @@ -290,12 +290,12 @@ func TestService_DeleteExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( - "Update", mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("*models.Experiment"), + "Update", context.TODO(), mock.AnythingOfType("*models.Experiment"), ).Return(errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -318,7 +318,7 @@ func TestService_GetExperiment_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), Name: "name", @@ -414,7 +414,7 @@ func TestService_GetExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(nil, errors.New("experiment not found")) return NewService( &config.ServiceConfig{}, @@ -438,7 +438,7 @@ func TestService_GetExperimentByName_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), Name: "name", @@ -518,7 +518,7 @@ func TestService_GetExperimentByName_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -536,7 +536,7 @@ func TestService_GetExperimentByName_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByName", mock.AnythingOfType("*context.emptyCtx"), "name", + "GetByName", context.TODO(), "name", ).Return(nil, nil) return NewService( &config.ServiceConfig{}, @@ -560,13 +560,13 @@ func TestService_RestoreExperiment_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( "Update", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(experiment *models.Experiment) bool { assert.Equal(t, models.LifecycleStageActive, experiment.LifecycleStage) assert.NotNil(t, experiment.LastUpdateTime) @@ -632,7 +632,7 @@ func TestService_RestoreExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(nil, errors.New("experiment not found")) return NewService( &config.ServiceConfig{}, @@ -650,12 +650,12 @@ func TestService_RestoreExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( - "Update", mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("*models.Experiment"), + "Update", context.TODO(), mock.AnythingOfType("*models.Experiment"), ).Return(errors.New("database error")) return NewService( &config.ServiceConfig{}, @@ -678,7 +678,7 @@ func TestService_SetExperimentTag_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) @@ -686,7 +686,7 @@ func TestService_SetExperimentTag_Ok(t *testing.T) { tagsRepository := repositories.MockTagRepositoryProvider{} tagsRepository.On( "CreateExperimentTag", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(tag *models.ExperimentTag) bool { assert.Equal(t, "key", tag.Key) assert.Equal(t, "value", tag.Value) @@ -770,7 +770,7 @@ func TestService_SetExperimentTag_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(nil, errors.New("experiment not found")) return NewService( &config.ServiceConfig{}, @@ -789,14 +789,14 @@ func TestService_SetExperimentTag_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) tagRepository := repositories.MockTagRepositoryProvider{} tagRepository.On( "CreateExperimentTag", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.AnythingOfType("*models.ExperimentTag"), ).Return(errors.New("database error")) @@ -821,13 +821,13 @@ func TestService_UpdateExperiment_Ok(t *testing.T) { // init repository mocks. experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( "Update", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(experiment *models.Experiment) bool { assert.Equal(t, "name", experiment.Name) assert.NotNil(t, experiment.LastUpdateTime) @@ -910,7 +910,7 @@ func TestService_UpdateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(nil, errors.New("experiment not found")) return NewService( &config.ServiceConfig{}, @@ -929,12 +929,12 @@ func TestService_UpdateExperiment_Error(t *testing.T) { service: func() *Service { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( - "GetByID", mock.AnythingOfType("*context.emptyCtx"), int32(1), + "GetByID", context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), }, nil) experimentRepository.On( - "Update", mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("*models.Experiment"), + "Update", context.TODO(), mock.AnythingOfType("*models.Experiment"), ).Return(errors.New("database error")) return NewService( &config.ServiceConfig{}, diff --git a/pkg/api/mlflow/service/metric/service_test.go b/pkg/api/mlflow/service/metric/service_test.go index c4868299e..68adfca94 100644 --- a/pkg/api/mlflow/service/metric/service_test.go +++ b/pkg/api/mlflow/service/metric/service_test.go @@ -20,7 +20,7 @@ func TestService_GetMetricHistory_Ok(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistoryByRunIDAndKey", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", "key", ).Return([]models.Metric{ @@ -89,7 +89,7 @@ func TestService_GetMetricHistory_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistoryByRunIDAndKey", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", "key", ).Return(nil, errors.New("database error")) @@ -112,7 +112,7 @@ func TestService_GetMetricHistoryBulk_Ok(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistoryBulk", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), []string{"1", "2"}, "key", 10, @@ -201,7 +201,7 @@ func TestService_GetMetricHistoryBulk_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistoryBulk", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), []string{"1"}, "key", 10, @@ -225,7 +225,7 @@ func TestNewService_GetMetricHistories_Ok(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistories", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), []string{"1", "2"}, mock.Anything, []string{"key1", "key2"}, @@ -311,7 +311,7 @@ func TestNewService_GetMetricHistories_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "GetMetricHistories", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.Anything, []string{"1"}, []string{"key1", "key2"}, diff --git a/pkg/api/mlflow/service/run/service_test.go b/pkg/api/mlflow/service/run/service_test.go index 7b7ba018c..eae3cf940 100644 --- a/pkg/api/mlflow/service/run/service_test.go +++ b/pkg/api/mlflow/service/run/service_test.go @@ -22,7 +22,7 @@ func TestService_CreateRun_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "Create", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(run *models.Run) bool { assert.NotEmpty(t, run.ID) assert.Equal(t, "name", run.Name) @@ -45,7 +45,7 @@ func TestService_CreateRun_Ok(t *testing.T) { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), int32(1), ).Return(&models.Experiment{ ID: common.GetPointer(int32(1)), @@ -121,7 +121,7 @@ func TestService_CreateRun_Error(t *testing.T) { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), int32(1), ).Return(nil, errors.New("database error")) return NewService( @@ -151,13 +151,13 @@ func TestService_CreateRun_Error(t *testing.T) { experimentRepository := repositories.MockExperimentRepositoryProvider{} experimentRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), int32(1), ).Return(&models.Experiment{ID: common.GetPointer(int32(1))}, nil) runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "Create", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(run *models.Run) bool { assert.NotEmpty(t, run.ID) assert.Equal(t, "name", run.Name) @@ -230,7 +230,7 @@ func TestService_UpdateRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -258,12 +258,12 @@ func TestService_RestoreRun_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ID: "1"}, nil) runRepository.On( "Update", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ ID: "1", DeletedTime: sql.NullInt64{Valid: false}, @@ -316,7 +316,7 @@ func TestService_RestoreRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -338,14 +338,14 @@ func TestService_RestoreRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", }, nil) runRepository.On( "Update", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(run *models.Run) bool { assert.Equal(t, "1", run.ID) assert.Equal(t, sql.NullInt64{}, run.DeletedTime) @@ -378,7 +378,7 @@ func TestService_SetRunTag_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return( @@ -386,7 +386,7 @@ func TestService_SetRunTag_Ok(t *testing.T) { ) runRepository.On( "SetRunTagsBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ID: "1", LifecycleStage: models.LifecycleStageActive}, 1, []models.Tag{{RunID: "1", Key: "key", Value: "value"}}, @@ -416,12 +416,12 @@ func TestService_DeleteRun_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ID: "1"}, nil) runRepository.On( "Archive", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ID: "1"}, ).Return(nil) @@ -470,7 +470,7 @@ func TestService_DeleteRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -492,7 +492,7 @@ func TestService_DeleteRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -514,14 +514,14 @@ func TestService_DeleteRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", }, nil) runRepository.On( "Archive", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(run *models.Run) bool { assert.Equal(t, "1", run.ID) return true @@ -579,7 +579,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, errors.New("database error")) @@ -602,7 +602,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, nil) @@ -626,7 +626,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -636,7 +636,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { tagRepository := repositories.MockTagRepositoryProvider{} tagRepository.On( "GetByRunIDAndKey", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", "key", ).Return(nil, errors.New("database error")) @@ -660,7 +660,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -670,7 +670,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { tagRepository := repositories.MockTagRepositoryProvider{} tagRepository.On( "GetByRunIDAndKey", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", "key", ).Return(&models.Tag{ @@ -680,7 +680,7 @@ func TestService_DeleteRunTag_Error(t *testing.T) { }, nil) tagRepository.On( "Delete", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(tag *models.Tag) bool { assert.Equal(t, "1", tag.RunID) assert.Equal(t, "key", tag.Key) @@ -713,7 +713,7 @@ func TestService_GetRun_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", @@ -831,7 +831,7 @@ func TestService_GetRun_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -859,7 +859,7 @@ func TestService_LogBatch_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -868,7 +868,7 @@ func TestService_LogBatch_Ok(t *testing.T) { }, nil) runRepository.On( "SetRunTagsBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ID: "1", LifecycleStage: models.LifecycleStageActive}, 100, mock.MatchedBy(func(tags []models.Tag) bool { @@ -881,7 +881,7 @@ func TestService_LogBatch_Ok(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 100, mock.MatchedBy(func(params []models.Param) bool { assert.Equal(t, "1", params[0].RunID) @@ -893,7 +893,7 @@ func TestService_LogBatch_Ok(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ID: "1", LifecycleStage: models.LifecycleStageActive}, 100, mock.MatchedBy(func(metrics []models.Metric) bool { @@ -973,7 +973,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, errors.New("database error")) @@ -996,7 +996,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, nil) @@ -1019,7 +1019,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, nil) @@ -1048,7 +1048,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1079,7 +1079,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1088,7 +1088,7 @@ func TestService_LogBatch_Error(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 100, []models.Param{ { @@ -1131,7 +1131,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1141,7 +1141,7 @@ func TestService_LogBatch_Error(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 100, []models.Param{ { @@ -1154,7 +1154,7 @@ func TestService_LogBatch_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ ID: "1", LifecycleStage: models.LifecycleStageActive, @@ -1209,7 +1209,7 @@ func TestService_LogBatch_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1218,7 +1218,7 @@ func TestService_LogBatch_Error(t *testing.T) { }, nil) runRepository.On( "SetRunTagsBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ ID: "1", LifecycleStage: models.LifecycleStageActive, @@ -1235,7 +1235,7 @@ func TestService_LogBatch_Error(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 100, []models.Param{ { @@ -1248,7 +1248,7 @@ func TestService_LogBatch_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ ID: "1", LifecycleStage: models.LifecycleStageActive, @@ -1289,7 +1289,7 @@ func TestService_LogMetric_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", @@ -1298,7 +1298,7 @@ func TestService_LogMetric_Ok(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), &models.Run{ID: "1", LifecycleStage: models.LifecycleStageActive}, 1, mock.MatchedBy(func(metrics []models.Metric) bool { @@ -1398,7 +1398,7 @@ func TestService_LogMetric_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(nil, errors.New("database error")) return NewService( @@ -1423,7 +1423,7 @@ func TestService_LogMetric_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", @@ -1451,7 +1451,7 @@ func TestService_LogMetric_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByID", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", ).Return(&models.Run{ ID: "1", @@ -1459,7 +1459,7 @@ func TestService_LogMetric_Error(t *testing.T) { metricRepository := repositories.MockMetricRepositoryProvider{} metricRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), mock.MatchedBy(func(run *models.Run) bool { assert.Equal(t, "1", run.ID) return true @@ -1500,7 +1500,7 @@ func TestService_LogParam_Ok(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1510,7 +1510,7 @@ func TestService_LogParam_Ok(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 1, mock.MatchedBy(func(params []models.Param) bool { assert.Equal(t, "1", params[0].RunID) @@ -1587,7 +1587,7 @@ func TestService_LogParam_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, errors.New("database error")) @@ -1612,7 +1612,7 @@ func TestService_LogParam_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(nil, nil) @@ -1637,7 +1637,7 @@ func TestService_LogParam_Error(t *testing.T) { runRepository := repositories.MockRunRepositoryProvider{} runRepository.On( "GetByIDAndLifecycleStage", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), "1", models.LifecycleStageActive, ).Return(&models.Run{ @@ -1647,7 +1647,7 @@ func TestService_LogParam_Error(t *testing.T) { paramRepository := repositories.MockParamRepositoryProvider{} paramRepository.On( "CreateBatch", - mock.AnythingOfType("*context.emptyCtx"), + context.TODO(), 1, mock.MatchedBy(func(params []models.Param) bool { assert.Equal(t, 1, len(params)) diff --git a/batch.py b/python/batch.py similarity index 84% rename from batch.py rename to python/batch.py index 0d29028bf..f9097859e 100644 --- a/batch.py +++ b/python/batch.py @@ -3,12 +3,15 @@ import pandas as pd import pyarrow as pa - from mlflow.entities import ViewType from mlflow.exceptions import MlflowException from mlflow.store.tracking.rest_store import RestStore from mlflow.tracking import MlflowClient -from mlflow.tracking.fluent import search_experiments, get_experiment_by_name, _get_experiment_id +from mlflow.tracking.fluent import ( + _get_experiment_id, + get_experiment_by_name, + search_experiments, +) from mlflow.utils.rest_utils import http_request from mlflow.utils.string_utils import is_string_type @@ -36,7 +39,7 @@ def get_metric_histories( :param metric_keys: List of metric keys to get the metric histories for. :param run_view_type: One of enum values ``ACTIVE_ONLY``, ``DELETED_ONLY``, or ``ALL`` runs defined in :py:class:`mlflow.entities.ViewType`. - :param max_results: The maximum number of metric values to put in the dataframe. Default is + :param max_results: The maximum number of metric values to put in the dataframe. Default is 10,000,000 to avoid causing out-of-memory issues on the user's machine. :param search_all_experiments: Boolean specifying whether all experiments should be searched. Only honored if ``experiment_ids`` is ``[]`` or ``None``. @@ -54,28 +57,22 @@ def get_metric_histories( raise MlflowException("Not implemented") if index not in ("step", "timestamp"): - raise ValueError( - f"Unsupported index: {index}. Supported string values are 'step' or 'timestamp'") + raise ValueError(f"Unsupported index: {index}. Supported string values are 'step' or 'timestamp'") no_exp_ids = experiment_ids is None or len(experiment_ids) == 0 no_exp_names = experiment_names is None or len(experiment_names) == 0 no_run_ids = run_ids is None or len(run_ids) == 0 no_ids_or_names = no_exp_ids and no_exp_names and no_run_ids if not no_exp_ids and not no_exp_names: - raise ValueError( - message="Only experiment_ids or experiment_names can be used, but not both") + raise ValueError(message="Only experiment_ids or experiment_names can be used, but not both") if search_all_experiments and no_ids_or_names: - experiment_ids = [ - exp.experiment_id for exp in search_experiments(view_type=ViewType.ACTIVE_ONLY) - ] + experiment_ids = [exp.experiment_id for exp in search_experiments(view_type=ViewType.ACTIVE_ONLY)] elif no_ids_or_names: experiment_ids = _get_experiment_id() elif not no_exp_names: - experiments = [get_experiment_by_name( - n) for n in experiment_names if n is not None] - experiment_ids = [ - e.experiment_id for e in experiments if e is not None] + experiments = [get_experiment_by_name(n) for n in experiment_names if n is not None] + experiment_ids = [e.experiment_id for e in experiments if e is not None] if isinstance(experiment_ids, int) or is_string_type(experiment_ids): experiment_ids = [experiment_ids] @@ -88,8 +85,8 @@ def get_metric_histories( # full thing is a mess result = http_request( host_creds=MlflowClient()._tracking_client.store.get_host_creds(), - endpoint='/api/2.0/mlflow/metrics/get-histories', - method='POST', + endpoint="/api/2.0/mlflow/metrics/get-histories", + method="POST", json={ "experiment_ids": experiment_ids, "run_ids": run_ids, @@ -97,7 +94,8 @@ def get_metric_histories( "run_view_type": ViewType.to_string(run_view_type).upper(), "max_results": max_results, }, - stream=True) + stream=True, + ) if result.status_code != 200: result = result.json() diff --git a/python/pyproject.toml b/python/pyproject.toml new file mode 100644 index 000000000..9787c3bdf --- /dev/null +++ b/python/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 000000000..05182ab8b --- /dev/null +++ b/python/setup.py @@ -0,0 +1,66 @@ +import os +import subprocess + +from setuptools import find_packages, setup +from wheel.bdist_wheel import bdist_wheel + + +def get_long_description(): + with open("../README.md", "r", encoding="utf-8") as f: + return f.read() + + +def get_data_files(): + os = subprocess.check_output(["go", "env", "GOOS"]).strip().decode("utf-8") + return [("Scripts", ["../fml.exe"])] if os == "windows" else [("bin", ["../fml"])] + + +def get_version(): + version = os.environ.get("VERSION") + return version.replace("-", "+", 1) + + +def get_platform(): + os = subprocess.check_output(["go", "env", "GOOS"]).strip().decode("utf-8") + arch = subprocess.check_output(["go", "env", "GOARCH"]).strip().decode("utf-8") + plat = f"{os}_{arch}" + if plat == "darwin_amd64": + return "macosx_10_13_x86_64" + elif plat == "darwin_arm64": + return "macosx_11_0_arm64" + elif plat == "linux_amd64": + return "manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64" + elif plat == "linux_arm64": + return "manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64" + elif plat == "windows_amd64": + return "win_amd64" + else: + raise ValueError("not supported platform.") + + +class custom_bdist_wheel(bdist_wheel): + def finalize_options(self): + bdist_wheel.finalize_options(self) + # Mark us as not a pure python package + self.root_is_pure = False + + def get_tag(self): + return "py3", "none", get_platform() + + +setup( + name="fasttrackml", + version=get_version(), + description="Rewrite of the MLFlow tracking server with a focus on scalability.", + long_description=get_long_description(), + long_description_content_type="text/markdown", + packages=find_packages(), + include_package_data=True, + data_files=get_data_files(), + python_requires=">=3.6", + zip_safe=False, + ext_modules=[], + cmdclass=dict( + bdist_wheel=custom_bdist_wheel, + ), +)