├── .github
└── workflows
│ └── mlflow-js.yaml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── mlflow-site
├── .eslintrc.json
├── .gitignore
├── README.md
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│ └── assets
│ │ ├── GithubLogo.png
│ │ ├── LinkedInLogo.png
│ │ ├── MLflow-js-logo.png
│ │ ├── Mlflow-js-symbol.png
│ │ ├── austinpfp.png
│ │ ├── imageNotFound.jpg
│ │ ├── kylerpfp.png
│ │ ├── mlflow-js-logo-whitebg.png
│ │ ├── mlflow-ui-screenshot-new.png
│ │ ├── stephanypfp.png
│ │ ├── winstonpfp-square.png
│ │ └── yiqun.png
├── src
│ └── app
│ │ ├── components
│ │ ├── Button.tsx
│ │ ├── Demo.tsx
│ │ ├── DemoCard.tsx
│ │ ├── FeatureCard.tsx
│ │ ├── Features.tsx
│ │ ├── Headline.tsx
│ │ ├── Method.tsx
│ │ ├── MethodBar.tsx
│ │ ├── MethodRequest.tsx
│ │ ├── NavBar.tsx
│ │ ├── Team.tsx
│ │ └── TeamCard.tsx
│ │ ├── documentation
│ │ ├── documentation.css
│ │ └── page.tsx
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ ├── GeistMonoVF.woff
│ │ └── GeistVF.woff
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ └── page.tsx
├── tailwind.config.ts
└── tsconfig.json
└── mlflow
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── docker-compose-test.yml
├── docker-compose.yml
├── docs
├── code-standards.md
└── tech-design-doc.md
├── eslint.config.mjs
├── examples
├── LinearRegressionExample.js
└── NeuralNetworkHyperparameterTuning.js
├── jest.config.ts
├── lib
├── index.d.ts
├── index.js
├── index.js.map
├── mlflow.d.ts
├── mlflow.js
├── mlflow.js.map
├── model-registry
│ ├── ModelRegistryClient.d.ts
│ ├── ModelRegistryClient.js
│ ├── ModelRegistryClient.js.map
│ ├── ModelVersionClient.d.ts
│ ├── ModelVersionClient.js
│ └── ModelVersionClient.js.map
├── tracking
│ ├── ExperimentClient.d.ts
│ ├── ExperimentClient.js
│ ├── ExperimentClient.js.map
│ ├── RunClient.d.ts
│ ├── RunClient.js
│ └── RunClient.js.map
├── utils
│ ├── apiError.d.ts
│ ├── apiError.js
│ ├── apiError.js.map
│ ├── apiRequest.d.ts
│ ├── apiRequest.js
│ ├── apiRequest.js.map
│ ├── interface.d.ts
│ ├── interface.js
│ └── interface.js.map
└── workflows
│ ├── ExperimentManager.d.ts
│ ├── ExperimentManager.js
│ ├── ExperimentManager.js.map
│ ├── ModelManager.d.ts
│ ├── ModelManager.js
│ ├── ModelManager.js.map
│ ├── RunManager.d.ts
│ ├── RunManager.js
│ └── RunManager.js.map
├── package-lock.json
├── package.json
├── src
├── index.ts
├── mlflow.ts
├── model-registry
│ ├── ModelRegistryClient.ts
│ └── ModelVersionClient.ts
├── tracking
│ ├── ExperimentClient.ts
│ └── RunClient.ts
├── utils
│ ├── apiError.ts
│ ├── apiRequest.ts
│ └── interface.ts
└── workflows
│ ├── ExperimentManager.ts
│ ├── ModelManager.ts
│ └── RunManager.ts
├── tests
├── ExperimentClient.test.ts
├── ExperimentManager.test.ts
├── ModelManager.test.ts
├── ModelRegistryClient.test.ts
├── ModelVersionClient.test.ts
├── RunClient.test.ts
├── RunManager.test.ts
└── testUtils.ts
├── tsconfig.json
└── tsconfig.test.json
/.github/workflows/mlflow-js.yaml:
--------------------------------------------------------------------------------
1 | name: mlflow
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | - dev
7 |
8 | jobs:
9 | build-and-test:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout code
13 | uses: actions/checkout@v4
14 |
15 | - name: Use Node.js
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version: '22.7'
19 |
20 | - name: Install dependencies
21 | working-directory: ./mlflow
22 | run: npm ci
23 |
24 | - name: Eslint
25 | working-directory: ./mlflow
26 | run: npm run lint
27 |
28 | - name: Set up Docker Buildx
29 | uses: docker/setup-buildx-action@v3
30 |
31 | - name: Run MLflow server
32 | run: |
33 | docker run -d -p 5002:5002 --name mlflow-container ghcr.io/mlflow/mlflow:latest mlflow server --host 0.0.0.0 --port 5002
34 | sleep 30
35 |
36 | - name: Run tests
37 | working-directory: ./mlflow
38 | run: npm run test
39 |
40 | - name: Stop MLflow server
41 | run: docker stop mlflow-container
42 |
43 | - name: Build
44 | working-directory: ./mlflow
45 | run: npm run build
46 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | We are always open to accepting any potential contributions. Here is how you can contribute:
4 |
5 | 1. Fork the repository
6 | 2. Clone your forked repository
7 |
8 | ```bash
9 | git clone https://github.com/your-username/repository-name.git
10 | ```
11 |
12 | 3. Create your feature branch
13 |
14 | ```bash
15 | git checkout -b feature/AmazingFeature
16 | ```
17 |
18 | 4. Install dependencies for both mlflow and mlflow-site directories
19 |
20 | ```bash
21 | cd /mlflow && npm install
22 | cd ../mlflow-site && npm install
23 | ```
24 |
25 | 5. Start the MLflow Tracking Server
26 |
27 | ```bash
28 | cd ../mlflow && npm run docker
29 | ```
30 |
31 | This will launch the MLflow UI on your local machine at `http://localhost:5001`.
32 |
33 | 6. Make your changes
34 |
35 | 7. Run ESLint to check code style
36 |
37 | ```bash
38 | npm run lint
39 | ```
40 |
41 | 8. Run tests to ensure your changes don't break existing functionality
42 |
43 | (Make sure you have mlflow UI server running on port 5002. We set 5002 as our default port for testing.)
44 |
45 | ```bash
46 | cd /mlflow && npm run dockerTest # Run this in a separate terminal
47 | npm run test
48 | ```
49 |
50 | This will launch the MLflow UI on your local machine at `http://localhost:5002`, and run the Jest tests.
51 |
52 | 9. Add and commit your changes
53 |
54 | If the tests all pass:
55 |
56 | ```bash
57 | git add .
58 | git commit -m 'Add AmazingFeature'
59 | ```
60 |
61 | 10. Push to the branch
62 |
63 | ```bash
64 | git push origin feature/AmazingFeature
65 | ```
66 |
67 | 11. Open a Pull Request
68 |
69 | **Note:** Please ensure your code adheres to our style guidelines and includes appropriate documentation for any new features.
70 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Open Source Labs Beta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/mlflow-site/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/mlflow-site/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | ../.DS_Store
22 | *.pem
23 |
24 | # debug
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
29 | # local env files
30 | .env*.local
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
--------------------------------------------------------------------------------
/mlflow-site/README.md:
--------------------------------------------------------------------------------
1 | ## Getting Started
2 |
3 | First, run the development server:
4 |
5 | ```bash
6 | npm run dev
7 | # or
8 | yarn dev
9 | # or
10 | pnpm dev
11 | # or
12 | bun dev
13 | ```
14 |
15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
--------------------------------------------------------------------------------
/mlflow-site/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: 'https',
7 | hostname: 'i.giphy.com'
8 | },
9 | ],
10 | },
11 | };
12 |
13 | export default nextConfig;
14 |
--------------------------------------------------------------------------------
/mlflow-site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mlflow-site",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "14.2.15",
13 | "react": "^18",
14 | "react-dom": "^18"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^20",
18 | "@types/react": "^18",
19 | "@types/react-dom": "^18",
20 | "eslint": "^8",
21 | "eslint-config-next": "14.2.15",
22 | "postcss": "^8",
23 | "tailwindcss": "^3.4.1",
24 | "typescript": "^5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/mlflow-site/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/mlflow-site/public/assets/GithubLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/GithubLogo.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/LinkedInLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/LinkedInLogo.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/MLflow-js-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/MLflow-js-logo.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/Mlflow-js-symbol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/Mlflow-js-symbol.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/austinpfp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/austinpfp.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/imageNotFound.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/imageNotFound.jpg
--------------------------------------------------------------------------------
/mlflow-site/public/assets/kylerpfp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/kylerpfp.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/mlflow-js-logo-whitebg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/mlflow-js-logo-whitebg.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/mlflow-ui-screenshot-new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/mlflow-ui-screenshot-new.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/stephanypfp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/stephanypfp.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/winstonpfp-square.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/winstonpfp-square.png
--------------------------------------------------------------------------------
/mlflow-site/public/assets/yiqun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/public/assets/yiqun.png
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Button.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | const Button = () => {
4 | return (
5 |
17 | );
18 | };
19 |
20 | export default Button;
21 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Demo.tsx:
--------------------------------------------------------------------------------
1 | import DemoCard from "./DemoCard";
2 |
3 | const Demo = () => {
4 | const demos = [];
5 | const demoCardHeaders = [
6 | 'Manage experiments',
7 | 'Complete workflow',
8 | 'Visualize results in the MLflow UI'
9 | ];
10 | const demoCardBlurbs = [
11 | 'Create experiments with MLflow.js. Using built-in workflows, manage complex operations easily.',
12 | <>
13 | This example demonstrates how to use MLflow.js to support a full ML
14 | project with TensorFlow.js. It covers logging hyperparameters and metrics
15 | during training, evaluating model performance, registering high-performing
16 | models, and exploring results in the MLflow UI. Check out the full code
17 | example on{' '}
18 |
24 | GitHub
25 |
26 | .
27 | >,
28 | 'Once the run completes, the MLflow UI provides powerful visualization tools to analyze experiments. Compare training and testing metrics across different runs to track performance patterns, or create custom charts that combine any logged hyperparameters and metrics to identify optimal model configurations',
29 | ];
30 | const demoCardVideos = [
31 | 'https://player.vimeo.com/video/1023585657',
32 | 'https://player.vimeo.com/video/1029068988',
33 |
34 | ];
35 | for (let i = 0; i < 3; i++) {
36 | demos.push(
37 |
43 | );
44 | }
45 | return (
46 | {demos}
47 | );
48 | };
49 |
50 | export default Demo;
51 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/DemoCard.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 |
3 | const DemoCard = ({
4 | header,
5 | blurb,
6 | video
7 | }: {
8 | key: string;
9 | blurb: string | React.JSX.Element;
10 | header: string;
11 | video: string;
12 | }) => {
13 | if (video !== undefined) {
14 | return (
15 |
16 |
17 |
31 |
32 |
33 |
{header}
34 |
{blurb}
35 |
36 |
37 | );
38 | }
39 | else {
40 | return (
41 |
42 |
48 |
49 |
{header}
50 |
{blurb}
51 |
52 |
53 | );
54 | };
55 | };
56 |
57 | export default DemoCard;
58 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/FeatureCard.tsx:
--------------------------------------------------------------------------------
1 | const FeatureCard = ({ header, blurb }: {
2 | key: string,
3 | blurb: string,
4 | header: string
5 | }) => {
6 | return (
7 |
8 |
{header}
9 | {blurb}
10 |
11 | );
12 | };
13 |
14 | export default FeatureCard;
15 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Features.tsx:
--------------------------------------------------------------------------------
1 | import FeatureCard from "./FeatureCard";
2 |
3 | const Features = () => {
4 | const featureHeader = 'MLOps in Javascript, made simple.';
5 | const featureLongBlurb = `
6 | MLflow.js is an open source JavaScript client library, bringing MLflow's powerful capabilities to JavaScript and TypeScript environments. It makes machine learning experimentation and model management intuitive for JavaScript developers through a clean, Promise-based API. Built with TypeScript, it provides comprehensive access to MLflow's REST API while adding streamlined abstractions for common ML workflows. Whether you're tracking experiments with TensorFlow.js, automating retraining pipelines, or managing A/B tests, MLflow.js helps you organize and version everything in one place.
7 |
8 | `;
9 | const cards = [];
10 | const featureCardHeaders = [
11 | 'Effortless integration',
12 | 'Streamlined MLOps',
13 | 'For the modern web developer',
14 | 'Dive deeper',
15 | ];
16 | const featureCardBlurbs = [
17 | 'Connect your JavaScript stack directly to MLflow with minimal setup.',
18 | 'Automate key MLOps tasks directly from Node.js, simplifying workflow management. Manage experiments, runs, model registry and model version management with dedicated methods.',
19 | 'Designed specifically for JavaScript developers: no Python knowledge required.',
20 | 'Execute complex MLOps tasks with a single function call with MLflow.js\'s powerful built-in workflows.'
21 |
22 | ];
23 | for (let i = 0; i < 4; i++) {
24 | cards.push(
25 |
30 | );
31 | }
32 | return (
33 |
34 |
{featureHeader}
35 |
{featureLongBlurb}
36 |
{cards}
37 |
38 | );
39 | };
40 |
41 | export default Features;
42 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Headline.tsx:
--------------------------------------------------------------------------------
1 | import Button from './Button';
2 |
3 | const Headline = () => {
4 | return (
5 |
6 |
ML workflow for Javascript
7 |
8 | Harness MLflow's functionality for your Javascript application with
9 | MLflow.js
10 |
11 |
12 |
13 | );
14 | };
15 |
16 | export default Headline;
17 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Method.tsx:
--------------------------------------------------------------------------------
1 | import MethodRequest from './MethodRequest';
2 |
3 | interface MethodIndividualProps {
4 | name: string;
5 | description: string;
6 | requestProps: Array<{ name: string; type: string; description: string }>;
7 | responseType: string;
8 | responseDescription: string;
9 | }
10 |
11 | const Method: React.FC = ({
12 | name,
13 | description,
14 | requestProps,
15 | responseType,
16 | responseDescription,
17 | }) => {
18 | return (
19 |
20 |
{name}
21 |
{description}
22 |
23 |
Parameters
24 |
25 |
26 |
Field Name
27 |
Type
28 |
29 | Description
30 |
31 |
32 | {requestProps.map((method, index) => (
33 |
40 | ))}
41 |
42 |
Returns
43 |
44 |
Type
45 |
Description
46 |
47 |
48 |
49 | {responseType}
50 |
51 |
52 | {responseDescription}
53 |
54 |
55 |
56 |
57 | );
58 | };
59 |
60 | export default Method;
61 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/MethodBar.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | interface MethodBarIndividualProps {
4 | name: string;
5 | }
6 |
7 | const MethodBarIndividual: React.FC = ({ name }) => {
8 | return (
9 | {
12 | const element = document.getElementById(`${name}`);
13 | element?.scrollIntoView({ behavior: 'smooth' });
14 | }}
15 | >
16 | {name}
17 |
18 | );
19 | };
20 |
21 | export default MethodBarIndividual;
22 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/MethodRequest.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | interface keystring {
4 | name: string
5 | type: string
6 | description: string
7 | num: number
8 | }
9 |
10 | const MethodRequest: React.FC = ( property ) => {
11 | if (property.num % 2 === 0) {
12 | return (
13 |
14 |
{property.name}
15 |
{property.type}
16 |
{property.description}
17 |
18 | );
19 | } else {
20 | return (
21 |
22 |
{property.name}
23 |
{property.type}
24 |
{property.description}
25 |
26 | );
27 | };
28 | }
29 |
30 | export default MethodRequest;
31 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/NavBar.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import Image from 'next/image';
4 |
5 | const NavBar = () => {
6 | return (
7 |
8 |
9 |
16 |
17 |
18 |
{
20 | const element = document.getElementById('headline');
21 | element?.scrollIntoView({ behavior: 'smooth' });
22 | }}
23 | className='navBarLinksHome'
24 | >
25 | Home
26 |
27 |
{
29 | const element = document.getElementById('features');
30 | element?.scrollIntoView({ behavior: 'smooth' });
31 | }}
32 | className='navBarLinksFeatures'
33 | >
34 | Features
35 |
36 |
{
38 | const element = document.getElementById('demo');
39 | element?.scrollIntoView({ behavior: 'smooth' });
40 | }}
41 | className='navBarLinksDemo'
42 | >
43 | Demo
44 |
45 |
{
47 | const element = document.getElementById('team');
48 | element?.scrollIntoView({ behavior: 'smooth' });
49 | }}
50 | className='navBarLinksTeam'
51 | >
52 | Team
53 |
54 |
58 |
65 |
66 |
67 |
68 | );
69 | };
70 |
71 | export default NavBar;
72 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/Team.tsx:
--------------------------------------------------------------------------------
1 | import TeamCard from './TeamCard';
2 |
3 | const Team = () => {
4 | const teamArray = [
5 | {
6 | name: 'Yiqun Zheng',
7 | github: 'https://github.com/yiqunzheng',
8 | linkedIn: 'https://www.linkedin.com/in/yiqunzheng/',
9 | pfp: '/assets/yiqun.png',
10 | },
11 | {
12 | name: 'Kyler Chiago',
13 | github: 'https://github.com/Kyler-Chiago',
14 | linkedIn: 'https://www.linkedin.com/in/kyler-chiago/',
15 | pfp: '/assets/kylerpfp.png',
16 | },
17 | {
18 | name: 'Austin Fraser',
19 | github: 'https://github.com/austinbfraser',
20 | linkedIn: 'http://www.linkedin.com/in/austin-fraser',
21 | pfp: '/assets/austinpfp.png',
22 | },
23 | {
24 | name: 'Stephany Ho',
25 | github: 'https://github.com/seneyu/',
26 | linkedIn: 'https://www.linkedin.com/in/stephanyho/',
27 | pfp: '/assets/stephanypfp.png',
28 | },
29 | {
30 | name: 'Winston Ludlam',
31 | github: 'https://github.com/winjolu/',
32 | linkedIn: 'https://www.linkedin.com/in/wjludlam/',
33 | pfp: '/assets/winstonpfp-square.png',
34 | },
35 | ];
36 |
37 | return (
38 |
39 |
Meet the team
40 |
41 | {teamArray.map((member, index) => (
42 |
49 | ))}
50 |
51 |
52 | );
53 | };
54 |
55 | export default Team;
56 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/components/TeamCard.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 |
3 | interface TeamCardProps {
4 | name: string;
5 | github: string;
6 | linkedIn: string;
7 | pfp: string;
8 | }
9 |
10 | const TeamCard: React.FC = ({ name, github, linkedIn, pfp }) => {
11 | return (
12 |
13 |
14 |
{name}
15 |
33 |
34 | );
35 | };
36 |
37 | export default TeamCard;
38 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/documentation/documentation.css:
--------------------------------------------------------------------------------
1 | .documentationWrapper {
2 | position: fixed;
3 | width: 100%;
4 | height: 100%;
5 | left: 0;
6 | top: 0;
7 | display: grid;
8 | grid-template-columns: 300px 1fr;
9 | grid-template-rows: 50px 1fr;
10 | }
11 |
12 | .documentationHeader {
13 | grid-column: 1/3;
14 | border-bottom: 1px solid black;
15 | display: grid;
16 | align-items: center;
17 | }
18 |
19 | .documentationImage {
20 | margin-left: 1rem;
21 | }
22 |
23 | .mlFlowOfficialLink {
24 | color: rgb(1, 148, 226)
25 | }
26 |
27 | .mlFlowReference {
28 | font-size: 1.5rem;
29 | }
30 |
31 | .documentationLeftSideBar {
32 | overflow-y: auto;
33 | overflow-x: hidden;
34 | scrollbar-width: none;
35 | border-right: 1px solid black;
36 | }
37 |
38 | .documentationMainWrapper {
39 | display: grid;
40 | width: 100%;
41 | grid-template-columns: 2rem 1fr 2rem;
42 | overflow-y: auto;
43 | overflow-x: auto;
44 | scrollbar-width: thin;
45 | text-wrap: wrap;
46 | }
47 |
48 | .documentationMain {
49 | grid-column: 2;
50 | }
51 |
52 | .documentationLeftHeader {
53 | padding-left: 10px;
54 | padding-right: 1rem;
55 | font-size: 1.4rem;
56 | cursor: pointer;
57 | }
58 |
59 | .documentationLeftHeader:hover {
60 | background-color: rgb(132, 185, 46);
61 | }
62 |
63 | .documentationLeftHeader2 {
64 | padding-left: 10px;
65 | padding-right: 1rem;
66 | font-size: 1.2rem;
67 | cursor: pointer;
68 | }
69 |
70 | .documentationLeftHeader2:hover {
71 | background-color: rgb(132, 185, 46);
72 | }
73 |
74 | .method {
75 | margin-bottom: 2rem;
76 | }
77 |
78 | .methodsHeader {
79 | font-size: 3rem;
80 | }
81 |
82 | .methodsHeader2 {
83 | font-size: 2.5rem;
84 | }
85 |
86 | .methodBarIndividual {
87 | cursor: pointer;
88 | padding-left: 1rem;
89 | padding-right: 1rem;
90 | }
91 |
92 | .methodBarIndividual:hover {
93 | background-color: rgb(132, 185, 46);
94 | }
95 |
96 | .methodName {
97 | font-size: 2rem;
98 | }
99 |
100 | .methodDescription {
101 | font-size: 1rem;
102 | }
103 |
104 | .methodRequest {
105 | display: grid;
106 | width: 100%;
107 | grid-template-columns: calc(100%/3) calc(100%/3) calc(100%/3);
108 | grid-template-rows: 100%;
109 | }
110 |
111 | .methodRequestBG {
112 | background-color: rgb(165, 211, 51);
113 | }
114 |
115 | .methodRequestLeft {
116 | border: 1px solid black;
117 | border-right: 0px;
118 | }
119 |
120 | .methodRequestMid {
121 | border: 1px solid black;
122 | }
123 |
124 | .methodRequestRight {
125 | border: 1px solid black;
126 | border-left: 0px;
127 | }
128 |
129 | .mRHeader {
130 | font-weight: bold;
131 | }
132 |
133 | .responseStructure {
134 | font-size: 1.7rem;
135 | }
136 |
137 | .responseFormat {
138 | display: grid;
139 | grid-template-columns: calc(100% / 3) calc(200% / 3);
140 | }
141 |
142 | .responseFormatHeader {
143 | font-weight: bold;
144 | }
145 |
146 | .textLeftPadding {
147 | padding-left: 0.8rem;
148 | }
149 |
150 | .documentationImageLink {
151 | width: fit-content;
152 | height: fit-content;
153 | }
154 |
155 | @media (max-width: 1000px) {
156 | .documentationLeftSideBar {
157 | display: none;
158 | }
159 |
160 | .documentationMainWrapper {
161 | grid-column: 1/3;
162 | grid-template-columns: 1rem minmax(340px, 1fr) calc(1rem+20px);
163 | }
164 |
165 | .mlFlowOfficialLink {
166 | word-break: break-all;
167 | }
168 |
169 | .textLeftPadding {
170 | padding-left: 0.4rem;
171 | }
172 |
173 | .textHorizontalOverflow::-webkit-scrollbar {
174 | height: 10px;
175 | }
176 | }
177 |
178 | .textHorizontalOverflow {
179 | overflow-x: auto;
180 | }
--------------------------------------------------------------------------------
/mlflow-site/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/src/app/favicon.ico
--------------------------------------------------------------------------------
/mlflow-site/src/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/src/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/mlflow-site/src/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oslabs-beta/mlflow-js/f61b9178af3405a659f1d72b198f9f061ca48616/mlflow-site/src/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/mlflow-site/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
2 | @tailwind base;
3 | @tailwind components;
4 | @tailwind utilities;
5 |
6 | body {
7 | color: var(--foreground);
8 | background: var(--background);
9 | font-family: Inter;
10 | font-size: 1rem;
11 | color: rgb(0, 0, 0);
12 | }
13 |
14 | @layer utilities {
15 | .text-balance {
16 | text-wrap: balance;
17 | }
18 | }
19 |
20 | .fullScreen {
21 | position: fixed;
22 | width: 100%;
23 | height: 100%;
24 | left: 0;
25 | top: 0;
26 | }
27 |
28 | .wrapper {
29 | position: absolute;
30 | background: rgb(51, 51, 58);
31 | width: 100%;
32 | height: 100%;
33 | display: grid;
34 | grid-template-columns: 1fr 100vw 1fr;
35 | grid-template-rows: 1fr;
36 | overflow-y: auto;
37 | overflow-x: hidden;
38 | }
39 |
40 | ::-webkit-scrollbar {
41 | width: 0px;
42 | }
43 |
44 | /* Track */
45 | ::-webkit-scrollbar-track {
46 | background: #262626;
47 | }
48 |
49 | /* Handle */
50 | ::-webkit-scrollbar-thumb {
51 | background: #5c5c5c;
52 | }
53 |
54 | /* Handle on hover */
55 | ::-webkit-scrollbar-thumb:hover {
56 | background: #515151;
57 | }
58 |
59 | .mobileWrapper {
60 | background: rgb(255, 255, 255);
61 | width: 100%;
62 | height: 100%;
63 | grid-column: 2;
64 | grid-row: 1;
65 | display: grid;
66 | grid-template-columns:
67 | 1vw clamp(1.3rem, 6vw, 8vw) 1fr clamp(1.3rem, 6vw, 8vw)
68 | 1vw;
69 | grid-template-rows: 1.3rem min-content 1fr min-content 1.3rem;
70 | }
71 |
72 | @media (min-width: 1000px) {
73 | ::-webkit-scrollbar {
74 | width: 10px;
75 | }
76 |
77 | .mobileWrapper {
78 | grid-template-columns: 1vw 8vw 1fr calc(8vw + 10px) calc(1vw + 10px);
79 | }
80 | }
81 |
82 | .navBar {
83 | grid-column: 2/5;
84 | grid-row: 2;
85 | width: 100%;
86 | height: 100%;
87 | display: grid;
88 | grid-template-columns: auto auto;
89 | grid-template-rows: 100%;
90 | font-size: clamp(1rem, 4.43vw, 1.2rem);
91 | }
92 |
93 | .mlflow-logo {
94 | width: clamp(4rem, 17.72vw, 9rem);
95 | height: auto;
96 | }
97 |
98 | .navBarLinks {
99 | grid-column: 2;
100 | grid-row: 1;
101 | width: 100%;
102 | height: 100%;
103 | display: grid;
104 | grid-template-columns: repeat(calc(100% / 5), 5);
105 | grid-template-rows: 100%;
106 | align-items: center;
107 | justify-content: right;
108 | column-gap: 2.8vw;
109 | }
110 |
111 | .navBarLinksFeatures {
112 | grid-column: 2;
113 | }
114 |
115 | .navBarLinksDemo {
116 | grid-column: 3;
117 | }
118 |
119 | .navBarLinksTeam {
120 | grid-column: 4;
121 | }
122 |
123 | .navBarLinksGithub {
124 | grid-column: 5;
125 | }
126 |
127 | .navBarLinksHome:hover, .navBarLinksFeatures:hover, .navBarLinksDemo:hover, .navBarLinksTeam:hover {
128 | color: rgb(99, 158, 40);
129 | }
130 |
131 | .navbarGithub {
132 | width: clamp(1.5rem, 6.645vw, 1.8rem);
133 | transition: transform .7s ease-in-out;
134 | }
135 |
136 | .navbarGithub:hover {
137 | transform: rotate(10deg);
138 | }
139 |
140 | .navBarMlflow {
141 | color: rgb(66, 107, 31);
142 | font-size: clamp(1.2rem, 5.316vw, 1.9rem);
143 | font-family: Newsreader;
144 | display: flex;
145 | align-items: center;
146 | }
147 |
148 | .bigHeadline {
149 | font-size: clamp(1.7rem, 6.531vw, 5.25rem);
150 | margin-top: 7vw;
151 | font-family: Newsreader;
152 | align-self: center;
153 | }
154 |
155 | .headLineText {
156 | font-size: clamp(1.1rem, 4.873vw, 2.25rem);
157 | margin-bottom: 2vw;
158 | font-family: Newsreader;
159 | align-self: center;
160 | }
161 |
162 | .mobileInnerWrapper {
163 | grid-column: 3;
164 | grid-row: 3;
165 | width: 100%;
166 | height: 100%;
167 | text-align: center;
168 | }
169 |
170 | .team {
171 | grid-column: 2/5;
172 | grid-row: 4;
173 | width: 100%;
174 | height: fit-content;
175 | display: flex;
176 | justify-content: center;
177 | align-items: center;
178 | flex-direction: column;
179 | }
180 |
181 | .home {
182 | margin-top: 0.3rem;
183 | grid-column: 2/5;
184 | grid-row: 3;
185 | width: 100%;
186 | display: flex;
187 | flex-direction: column;
188 | }
189 |
190 | .homeButton {
191 | width: clamp(8rem, 24vw, 20rem);
192 | padding-left: clamp(0.375rem, 1.66125vw, 0.65625rem);
193 | padding-right: clamp(0.375rem, 1.66125vw, 0.65625rem);
194 | padding-top: clamp(0.375rem, 1.66125vw, 0.65625rem);
195 | padding-bottom: clamp(0.375rem, 1.66125vw, 0.65625rem);
196 | border-radius: clamp(0.3125rem, 1.384375vw, 0.546875rem);
197 | font-size: clamp(0.7rem, 3vw, 1.8rem);
198 | }
199 |
200 | .homeButton:hover {
201 | border: 1px solid black;
202 | }
203 |
204 | .homeButtonDownload {
205 | background-color: rgb(66, 107, 31);
206 | margin-right: 8px;
207 | margin-bottom: 5vw;
208 | }
209 |
210 | .homeButtonRead {
211 | background-color: rgb(204, 204, 204);
212 | }
213 |
214 | @media (min-width: 1000px) {
215 | .button {
216 | align-self: center;
217 | }
218 | }
219 |
220 | .features {
221 | grid-column: 2/5;
222 | grid-row: 3;
223 | width: 100%;
224 | display: grid;
225 | place-items: center;
226 | padding: 0.5rem;
227 | margin-bottom: 4rem;
228 | text-align: center;
229 | color: black;
230 | background-color: white;
231 | margin-top: clamp(1rem, 4.43vw, 3rem);
232 | font-family: Inter;
233 | }
234 |
235 | .featureHeader {
236 | font-size: clamp(1.3rem, 5.759vw, 3rem);
237 | margin-bottom: 0.5rem;
238 | font-family: Inter;
239 | }
240 |
241 | .featureLongBlurb {
242 | font-size: clamp(1rem, 4.43vw, 1.5rem);
243 | margin-bottom: 0.5rem;
244 | font-family: Inter;
245 | }
246 |
247 | .featureCard {
248 | color: black;
249 | width: 100%;
250 | background-color: rgb(217, 225, 210);
251 | display: grid;
252 | grid-template-columns: 100%;
253 | grid-template-rows: min-content;
254 | padding: 0.5rem;
255 | margin-bottom: 0.5rem;
256 | font-family: Inter;
257 | }
258 |
259 | .featureCardHeader {
260 | font-size: clamp(1.3rem, 5.316vw, 1.5rem);
261 | font-family: Inter;
262 | }
263 |
264 | .featureCardsSection {
265 | margin-top: 1rem;
266 | font-family: Inter;
267 | }
268 |
269 | @media (min-width: 1000px) {
270 | .featureCardsSection {
271 | display: grid;
272 | grid-template-columns: 50% 50%;
273 | column-gap: 10px;
274 | }
275 |
276 | .featureCard {
277 | text-align: left;
278 | }
279 | }
280 |
281 | .demo {
282 | grid-column: 2/5;
283 | grid-row: 3;
284 | width: 100%;
285 | display: grid;
286 | grid-template-columns: 100%;
287 | grid-template-rows: calc(100% / 3) calc(100% / 3) calc(100% / 3);
288 | color: black;
289 | background-color: white;
290 | margin-bottom: clamp(1rem, 4.43vw, 3rem);
291 | margin-top: 10vw;
292 | }
293 |
294 | .demoCard {
295 | gap: 1.25rem;
296 | padding: 0.25rem;
297 | margin-bottom: 4rem;
298 | text-align: center;
299 | }
300 |
301 | @media (min-width: 1000px) {
302 | .demoCard {
303 | display: grid;
304 | grid-template-columns: 50% 50%;
305 | column-gap: 10px;
306 | text-align: left;
307 | }
308 | }
309 |
310 | @media (max-width: 1000px) {
311 | .demoCardText {
312 | margin-top: 0.8rem;
313 | margin-bottom: 4rem;
314 | }
315 | }
316 |
317 | .demoCardHeader {
318 | font-size: clamp(1.3rem, 5.759vw, 2rem);
319 | }
320 |
321 | .demoCardInfo {
322 | font-size: clamp(1rem, 4vw, 1.25rem);
323 | }
324 |
325 | .demoSplit {
326 | width: 100%;
327 | display: grid;
328 | grid-template-columns: 100%;
329 | grid-template-rows: min-content;
330 | }
331 |
332 | .vimeoPlayer {
333 | margin-top: -35px;
334 | }
335 |
336 | #MLflow-ui-screenshot {
337 | margin-bottom: 10rem;
338 | }
339 |
340 | .teamHead {
341 | font-size: clamp(1.35rem, 5.9805vw, 2.376rem);
342 | }
343 |
344 | .teamCards {
345 | width: 100%;
346 | display: flex;
347 | justify-content: space-evenly;
348 | flex-wrap: wrap;
349 | }
350 |
351 | .teamcard {
352 | margin-top: 0.5rem;
353 | display: flex;
354 | flex-direction: column;
355 | justify-content: center;
356 | align-items: center;
357 | font-size: clamp(1rem, 4.43vw, 1.3rem);
358 | padding: clamp(0.22rem, 1.1927vw, 0.35rem);
359 | margin-left: 0.2rem;
360 | margin-right: 0.2rem;
361 | background-color: rgb(217, 225, 210);
362 | width: 170px;
363 | border-radius: 5px;
364 | }
365 |
366 | .teamCardImg {
367 | width: clamp(80px, 22.155vw, 100px);
368 | border: 1px solid black;
369 | }
370 |
371 | .teamcardLinks {
372 | display: grid;
373 | grid-template-columns: 45% 10% 45%;
374 | grid-template-rows: 100%;
375 | }
376 |
377 | .teamCardLink1 {
378 | grid-column: 1;
379 | }
380 |
381 | .teamCardLink2 {
382 | grid-column: 3;
383 | }
384 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import localFont from "next/font/local";
3 | import "./globals.css";
4 | import { Viewport } from "next";
5 |
6 | const geistSans = localFont({
7 | src: "./fonts/GeistVF.woff",
8 | variable: "--font-geist-sans",
9 | weight: "100 900",
10 | });
11 | const geistMono = localFont({
12 | src: "./fonts/GeistMonoVF.woff",
13 | variable: "--font-geist-mono",
14 | weight: "100 900",
15 | });
16 |
17 | export const metadata: Metadata = {
18 | title: "MLflow.js",
19 | description: "MLflow.js",
20 | };
21 |
22 | export const viewport: Viewport = {
23 | themeColor: "#000000",
24 | initialScale: 1,
25 | width: "device-width",
26 | maximumScale: 1,
27 | };
28 |
29 | export default function RootLayout({
30 | children,
31 | }: Readonly<{
32 | children: React.ReactNode;
33 | }>) {
34 | return (
35 |
36 |
39 | {children}
40 |
41 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/mlflow-site/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import NavBar from './components/NavBar';
2 | import Team from './components/Team';
3 | import Headline from './components/Headline';
4 | import Features from './components/Features';
5 | import Demo from './components/Demo';
6 |
7 | export default function Home() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/mlflow-site/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: "var(--background)",
13 | foreground: "var(--foreground)",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 | export default config;
20 |
--------------------------------------------------------------------------------
/mlflow-site/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/mlflow/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules/
3 |
4 | # Environment variables
5 | .env
6 |
7 | # IDE
8 | .vscode
9 |
10 | # Misc
11 | .DS_Store
12 | ../.DS_Store
13 |
14 | # Python / MLflow specific
15 | .venv/
16 | mlruns/
17 |
18 | # Temporary files
19 | temp/
20 |
21 | # Test coverage
22 | coverage/
23 |
24 |
25 |
26 | =
--------------------------------------------------------------------------------
/mlflow/Dockerfile:
--------------------------------------------------------------------------------
1 | # Dockerfile
2 | # Specify exact Node.js version for consistency
3 | FROM node:22.7.0
4 | WORKDIR /mlflow
5 | # Install necessary tools
6 | RUN apt-get update && apt-get install -y \
7 | curl \
8 | git \
9 | && rm -rf /var/lib/apt/lists/*
10 | # Copy package files
11 | # Uses package-lock.json for exact versions
12 | COPY package*.json ./
13 | # Install dependencies with exact versions
14 | RUN npm ci
15 | # Copy source code
16 | COPY . .
17 | # Build the project
18 | RUN npm run build
--------------------------------------------------------------------------------
/mlflow/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Open Source Labs Beta
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/mlflow/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # MLflow.js
4 |
5 | A JavaScript library designed to provide seamless integration with MLflow's REST API. This package offers access to all the essential endpoints for both the MLflow Tracking Server and Model Registry, along with high-level abstraction workflows, enabling efficient management of machine learning experiments and model lifecycle.
6 |
7 | # Install
8 |
9 | ```bash
10 | npm install mlflow-js
11 | ```
12 |
13 | # Usage
14 |
15 | An example of how to create an experiment:
16 |
17 | ```javascript
18 | import Mlflow from 'mlflow-js';
19 |
20 | // Initialize the MLflow client
21 | const mlflow = new Mlflow(process.env.MLFLOW_TRACKING_URI);
22 |
23 | // Create a new experiment
24 | async function createExperiment() {
25 | await mlflow.createExperiment('My Experiment');
26 | console.log('Experiment created successfully');
27 | }
28 |
29 | createExperiment();
30 | ```
31 |
32 | # Documentation
33 |
34 | See [https://www.mlflow-js.org/documentation](https://www.mlflow-js.org/documentation)
35 |
36 | # API
37 |
38 | ## Tracking Server
39 |
40 | - Experiment Client (8)
41 | - Create Experiment, Search Experiment, Get Experiment, Get Experiment By Name, Delete Experiment, Restore Experiment, Update Experiment, Set Experiment Tag
42 | - Run Client (15)
43 | - Create Run, Delete Run, Restore Run, Get Run, Update Run, Log Metric, Log Batch, Log Model, Log Inputs, Set Tag, Delete Tag, Log Param, Get Metric History, Search Runs, List Artifacts
44 |
45 | ## Model Registry
46 |
47 | - Model Registry Client (12)
48 | - Create, Registered Model, Get Registered Model, Rename Registered Model, Update Registered Model, Delete Registered Model, Get Latest Model Versions, Search Registered Models, Set Registered Model Tag, Delete Registered Model Tag, Set Registered Model Alias, Delete Registered Model Alias, Get Model Version By Alias
49 | - Model Version Client (9)
50 | - Create Model Version, Get Model Version, Update Model Version, Search Model Versions, Get Download URI for Model Version Artifacts, Transition Model Version Stage, Set Model Version Tag, Delete Model Version Tag, Delete Model Version
51 |
52 | ## High-Level Abstraction Workflows
53 |
54 | - Experiment Manager (3)
55 | - Run Existing Experiment, Run New Experiment, Experiment Summary
56 | - Run Manager (2)
57 | - Cleanup Runs, Copy Run
58 | - Model Manager (9)
59 | - Create Registered Model With Version, Update Registered Model Description And Tag, Update All Latest Model Version, Set Latest Model Version Tag, Set Latest Model Version Alias, Update Latest Model Version, Update All Model Version, Delete Latest Model Version, Create Model From Run With Best Metric
60 |
--------------------------------------------------------------------------------
/mlflow/docker-compose-test.yml:
--------------------------------------------------------------------------------
1 | # docker-compose.yml
2 | name: mlflowtest
3 | services:
4 | # MLflow server for testing
5 | mlflowtest:
6 | # The latest mlflow docker image
7 | image: ghcr.io/mlflow/mlflow
8 | ports:
9 | - "5002:5002"
10 | command: mlflow server --host 0.0.0.0 --port 5002
11 | healthcheck:
12 | test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5002/health')"]
13 | interval: 30s
14 | timeout: 10s
15 | retries: 3
16 | # Development environment to ensure consistency across contributors
17 | devtest:
18 | build:
19 | context: .
20 | dockerfile: Dockerfile
21 | volumes:
22 | - .:/mlflow # Mount code for live development
23 | - /mlflow/node_modules # Keep node_modules in container
24 | command: /bin/sh -c "while sleep 1000; do :; done" # Keep container running
25 | depends_on:
26 | mlflowtest:
27 | condition: service_healthy
--------------------------------------------------------------------------------
/mlflow/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # docker-compose.yml
2 | services:
3 | # MLflow server for testing
4 | mlflow:
5 | # The latest mlflow docker image
6 | image: ghcr.io/mlflow/mlflow
7 | ports:
8 | - "5001:5001"
9 | command: mlflow server --host 0.0.0.0 --port 5001
10 | healthcheck:
11 | test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5001/health')"]
12 | interval: 30s
13 | timeout: 10s
14 | retries: 3
15 | # Development environment to ensure consistency across contributors
16 | dev:
17 | build:
18 | context: .
19 | dockerfile: Dockerfile
20 | volumes:
21 | - .:/mlflow # Mount code for live development
22 | - /mlflow/node_modules # Keep node_modules in container
23 | command: /bin/sh -c "while sleep 1000; do :; done" # Keep container running
24 | depends_on:
25 | mlflow:
26 | condition: service_healthy
--------------------------------------------------------------------------------
/mlflow/docs/code-standards.md:
--------------------------------------------------------------------------------
1 | # TypeScript Code Standards
2 |
3 | ## File Structure and Naming
4 | - Use PascalCase for class files (e.g., `ModelRegistryClient.ts`)
5 | - Use camelCase for utility files (e.g., `apiRequest.ts`)
6 | - Use kebab-case for directory names (e.g., `model-registry`)
7 |
8 | ## Imports and Exports
9 | - Use named exports for utilities and interfaces
10 | - Use default exports for main classes
11 | - Group and sort imports:
12 | 1. External libraries
13 | 2. Internal modules
14 | 3. Relative imports
15 | - Within each group, sort alphabetically
16 | - For imports from other modules, use the path aliases defined in tsconfig.json
17 | - For imports within the same directory, use relative imports
18 |
19 | ## Naming Conventions
20 | - PascalCase for classes and interfaces
21 | - camelCase for methods, variables, and functions
22 | - UPPER_SNAKE_CASE for constants
23 |
24 | ## Documentation
25 | - Use JSDoc comments for classes, methods, and functions
26 | - Include parameter descriptions, return types, and thrown exceptions
27 | - Example:
28 | ```typescript
29 | /**
30 | * Creates a new registered model.
31 | * @param {string} name - The name of the model to register
32 | * @param {RegisteredModelTag[]} [tags] - Optional tags for the model
33 | * @param {string} [description] - Optional description for the model
34 | * @returns {Promise} The created registered model object
35 | * @throws {ApiError} If the API request fails
36 | */
37 | ```
38 |
39 | ## Error Handling Guide
40 |
41 | - For simple API calls, use the ApiError class:
42 |
43 | ```typescript
44 | if (!response.ok) {
45 | throw new ApiError(
46 | `Error: ${data.message || response.statusText}`,
47 | response.status
48 | );
49 | }
50 | ```
51 |
52 | - For complex functions, use try/catch blocks:
53 |
54 | ```typescript
55 | try {
56 | // complex operation
57 | } catch (error) {
58 | if (error instanceof ApiError) {
59 | console.error(`API Error (${error.statusCode}): ${error.message}`);
60 | throw error;
61 | } else {
62 | console.error('An unexpected error occurred:', error);
63 | throw new Error;
64 | }
65 | }
66 | ```
67 |
68 | ## Asynchronous Code
69 | - Use async/await for asynchronous operations
70 |
71 | ## Type Annotations
72 | - Use TypeScript type annotations consistently
73 | - Create interfaces for complex object structures
74 | - Use generics where appropriate
75 |
76 | ## Class and Method Structure
77 | - Utilize TypeScript features like access modifiers (public, private)
78 | - Use method signatures with proper TypeScript types
79 |
80 | ## Formatting
81 | - Use 2 spaces for indentation
82 | - Use single quotes for strings
83 | - Add semicolons at the end of statements
84 |
85 | ## Consistency
86 | - Maintain consistent style and patterns throughout the codebase
87 | - When in doubt, follow the existing patterns in the project
88 |
89 |
--------------------------------------------------------------------------------
/mlflow/docs/tech-design-doc.md:
--------------------------------------------------------------------------------
1 | # MLflow JavaScript Library Technical Design Document
2 |
3 |
4 | ## 1. Overview
5 |
6 |
7 | The MLflow-JS library aims to provide a comprehensive and intuitive interface for interacting with MLflow services in a JavaScript/TypeScript environment. It simplifies the integration with MLflow REST APIs by offering high-level methods for tracking, model management, and advanced workflows.
8 |
9 |
10 | ## 2. Architecture
11 |
12 |
13 | The library follows a modular architecture with a main `MLflow` class serving as the primary entry point and separate clients for different MLflow components and workflow managers.
14 |
15 |
16 | ### 2.1 Core Components
17 |
18 |
19 | 1. **MLflow**: Main class providing access to high-level abstractions and other components.
20 | 2. **Tracking**: Module for interacting with MLflow's tracking server.
21 | 3. **Model Registry**: Module for managing models in MLflow's model registry.
22 | 4. **Workflows**: Higher-level abstractions for common workflows.
23 | 5. **Utils**: Utility functions and classes used across the library.
24 |
25 |
26 | ### 2.2 Folder Structure
27 |
28 |
29 | ```
30 | mlflow-js/
31 | ├── src/
32 | │ ├── tracking/
33 | │ │ ├── ExperimentClient.ts
34 | │ │ ├── RunClient.ts
35 | │ ├── model-registry/
36 | │ │ ├── ModelRegistryClient.ts
37 | │ │ └── ModelVersionClient.ts
38 | │ ├── workflows/
39 | │ │ ├── ExperimentManager.ts
40 | │ │ ├── RunManager.ts
41 | │ │ └── ModelManager.ts
42 | │ ├── utils/
43 | │ │ ├── apiRequest.ts
44 | │ │ └── apiError.ts
45 | │ ├── mlflow.ts
46 | │ └── index.ts
47 | ├── tests/
48 | ├── lib/
49 | │ └── index.js
50 | ├── examples/
51 | └── docs/
52 | ```
53 |
54 |
55 | ## 3. Component Details
56 |
57 |
58 | ### 3.1 MLflow Class
59 |
60 |
61 | The `MLflow` class serves as the main entry point for the library. It provides:
62 | - Access to High-level abstractions for common workflows
63 | - Access to tracking and model registry components
64 | - Dynamic Method Delegation Approach/Dynamic Method Binding and getter access
65 |
66 |
67 | ### 3.2 Tracking Module
68 |
69 |
70 | Includes clients for interacting with MLflow's tracking server:
71 | - `ExperimentClient`: Manage experiments
72 | - `RunClient`: Create and manage runs, log metrics/params/artifacts
73 |
74 |
75 | ### 3.3 Model Registry Module
76 |
77 |
78 | Provides functionality for model management:
79 | - `ModelRegistryClient`: Register and manage models
80 | - `ModelVersionClient`: Handle model versioning and stage transitions
81 |
82 |
83 | ### 3.4 Workflows
84 |
85 |
86 | Higher-level abstractions for common workflows:
87 | - `ExperimentManager`: Manage experiment lifecycles
88 | - `RunManager`: Simplify run creation and management
89 | - `ModelManager`: Streamline model registration and promotion
90 |
91 |
92 | ### 3.5 Utils
93 |
94 |
95 | Utility classes and functions:
96 | - `apiRequest`: Handle HTTP requests to MLflow server
97 | - `ApiError`: Custom error class for API-related errors
98 |
99 |
100 | ## 4. Data Flow
101 |
102 |
103 | 1. User interacts with `MLflow` instance
104 | 2. `MLflow` delegates to appropriate abstraction or client
105 | 3. Client/abstraction uses `ApiRequest` to make HTTP requests
106 | 4. `ApiRequest` sends request to MLflow server
107 | 5. Response is processed and returned to user
108 |
109 |
110 | ## 5. Testing Strategy
111 |
112 |
113 | - Integration tests for API interactions
114 | - End-to-end tests with a real MLflow server and ML model
115 |
116 |
117 | ## 6. Documentation
118 |
119 |
120 | - Comprehensive API documentation generated from JSDoc comments
121 | - Usage examples for common scenarios
122 | - Tutorials for getting started and advanced usage
123 |
--------------------------------------------------------------------------------
/mlflow/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | import eslint from '@eslint/js';
4 | import tseslint from 'typescript-eslint';
5 |
6 | export default tseslint.config(
7 | eslint.configs.recommended,
8 | ...tseslint.configs.recommended,
9 | {
10 | ignores: ['docs', 'lib/**', 'examples'],
11 | },
12 | {
13 | rules: {
14 | '@typescript-eslint/no-explicit-any': 'off',
15 | 'no-console': 'off',
16 | },
17 | }
18 | );
19 |
--------------------------------------------------------------------------------
/mlflow/jest.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from '@jest/types';
2 |
3 | const config: Config.InitialOptions = {
4 | preset: 'ts-jest',
5 | testEnvironment: 'node',
6 | transform: {
7 | '^.+\\.tsx?$': ['ts-jest', { tsconfig: 'tsconfig.test.json' }],
8 | },
9 | moduleNameMapper: {
10 | '^@utils/(.*)$': '/src/utils/$1',
11 | '^@model-registry/(.*)$': '/src/model-registry/$1',
12 | '^@tracking/(.*)$': '/src/tracking/$1',
13 | '^@workflows/(.*)$': '/src/workflows/$1',
14 | },
15 | testTimeout: 30000,
16 | };
17 |
18 | export default config;
--------------------------------------------------------------------------------
/mlflow/lib/index.d.ts:
--------------------------------------------------------------------------------
1 | import Mlflow from './mlflow.js';
2 | export default Mlflow;
3 |
--------------------------------------------------------------------------------
/mlflow/lib/index.js:
--------------------------------------------------------------------------------
1 | import Mlflow from './mlflow.js';
2 | export default Mlflow;
3 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/mlflow/lib/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,eAAe,MAAM,CAAC"}
--------------------------------------------------------------------------------
/mlflow/lib/mlflow.d.ts:
--------------------------------------------------------------------------------
1 | import ExperimentClient from './tracking/ExperimentClient.js';
2 | import ExperimentManager from './workflows/ExperimentManager.js';
3 | import RunClient from './tracking/RunClient.js';
4 | import RunManager from './workflows/RunManager.js';
5 | import ModelRegistryClient from './model-registry/ModelRegistryClient.js';
6 | import ModelVersionClient from './model-registry/ModelVersionClient.js';
7 | import ModelManager from './workflows/ModelManager.js';
8 | declare class Mlflow {
9 | private components;
10 | constructor(trackingUri: string);
11 | private initializeMethods;
12 | getExperimentClient(): ExperimentClient;
13 | getRunClient(): RunClient;
14 | getModelRegistryClient(): ModelRegistryClient;
15 | getModelVersionClient(): ModelVersionClient;
16 | getExperimentManager(): ExperimentManager;
17 | getRunManager(): RunManager;
18 | getModelManager(): ModelManager;
19 | }
20 | export default Mlflow;
21 |
--------------------------------------------------------------------------------
/mlflow/lib/mlflow.js:
--------------------------------------------------------------------------------
1 | import ExperimentClient from './tracking/ExperimentClient.js';
2 | import ExperimentManager from './workflows/ExperimentManager.js';
3 | import RunClient from './tracking/RunClient.js';
4 | import RunManager from './workflows/RunManager.js';
5 | import ModelRegistryClient from './model-registry/ModelRegistryClient.js';
6 | import ModelVersionClient from './model-registry/ModelVersionClient.js';
7 | import ModelManager from './workflows/ModelManager.js';
8 | class Mlflow {
9 | constructor(trackingUri) {
10 | this.components = {
11 | experimentClient: new ExperimentClient(trackingUri),
12 | experimentManager: new ExperimentManager(trackingUri),
13 | runClient: new RunClient(trackingUri),
14 | runManager: new RunManager(trackingUri),
15 | modelRegistryClient: new ModelRegistryClient(trackingUri),
16 | modelVersionClient: new ModelVersionClient(trackingUri),
17 | modelManager: new ModelManager(trackingUri),
18 | };
19 | this.initializeMethods();
20 | }
21 | initializeMethods() {
22 | Object.keys(this.components).forEach((componentName) => {
23 | const component = this.components[componentName];
24 | Object.getOwnPropertyNames(Object.getPrototypeOf(component))
25 | .filter((name) => typeof component[name] === 'function' &&
26 | name !== 'constructor')
27 | .forEach((methodName) => {
28 | this[methodName] = (...args) => component[methodName](...args);
29 | });
30 | });
31 | }
32 | // Getter methods for direct access to clients and managers
33 | getExperimentClient() {
34 | return this.components.experimentClient;
35 | }
36 | getRunClient() {
37 | return this.components.runClient;
38 | }
39 | getModelRegistryClient() {
40 | return this.components.modelRegistryClient;
41 | }
42 | getModelVersionClient() {
43 | return this.components.modelVersionClient;
44 | }
45 | getExperimentManager() {
46 | return this.components.experimentManager;
47 | }
48 | getRunManager() {
49 | return this.components.runManager;
50 | }
51 | getModelManager() {
52 | return this.components.modelManager;
53 | }
54 | }
55 | export default Mlflow;
56 | //# sourceMappingURL=mlflow.js.map
--------------------------------------------------------------------------------
/mlflow/lib/mlflow.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"mlflow.js","sourceRoot":"","sources":["../src/mlflow.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,MAAM,6BAA6B,CAAC;AAC3D,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAC9D,OAAO,SAAS,MAAM,sBAAsB,CAAC;AAC7C,OAAO,UAAU,MAAM,wBAAwB,CAAC;AAChD,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AACvE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,YAAY,MAAM,0BAA0B,CAAC;AAIpD,MAAM,MAAM;IAWV,YAAY,WAAmB;QAC7B,IAAI,CAAC,UAAU,GAAG;YAChB,gBAAgB,EAAE,IAAI,gBAAgB,CAAC,WAAW,CAAC;YACnD,iBAAiB,EAAE,IAAI,iBAAiB,CAAC,WAAW,CAAC;YACrD,SAAS,EAAE,IAAI,SAAS,CAAC,WAAW,CAAC;YACrC,UAAU,EAAE,IAAI,UAAU,CAAC,WAAW,CAAC;YACvC,mBAAmB,EAAE,IAAI,mBAAmB,CAAC,WAAW,CAAC;YACzD,kBAAkB,EAAE,IAAI,kBAAkB,CAAC,WAAW,CAAC;YACvD,YAAY,EAAE,IAAI,YAAY,CAAC,WAAW,CAAC;SAC5C,CAAC;QAEF,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAC3B,CAAC;IAEO,iBAAiB;QACtB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAqB,CAAC,OAAO,CACvD,CAAC,aAAa,EAAE,EAAE;YAChB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YACjD,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;iBACzD,MAAM,CACL,CAAC,IAAI,EAAE,EAAE,CACP,OAAQ,SAAiB,CAAC,IAAI,CAAC,KAAK,UAAU;gBAC9C,IAAI,KAAK,aAAa,CACzB;iBACA,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE;gBACrB,IAAY,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAW,EAAE,EAAE,CAC5C,SAAiB,CAAC,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5C,CAAC,CAAC,CAAC;QACP,CAAC,CACF,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,mBAAmB;QACjB,OAAO,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;IAC1C,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,sBAAsB;QACpB,OAAO,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;IAC7C,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC;IAC5C,CAAC;IAED,oBAAoB;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC;IAC3C,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;IACpC,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;IACtC,CAAC;CACF;AAED,eAAe,MAAM,CAAC"}
--------------------------------------------------------------------------------
/mlflow/lib/model-registry/ModelRegistryClient.d.ts:
--------------------------------------------------------------------------------
1 | declare class ModelRegistryClient {
2 | private baseUrl;
3 | constructor(trackingUri: string);
4 | /**
5 | * Creates a new registered model.
6 | *
7 | * @param {string} name - The name of the model to register (required)
8 | * @param {Array<{key: string, value: string}>} [tags] - Optional tags for the model
9 | * @param {string} [description] - Optional description for the model
10 | * @returns {Promise} The created registered model object
11 | * @throws {ApiError} If the API request fails
12 | */
13 | createRegisteredModel(name: string, tags?: Array<{
14 | key: string;
15 | value: string;
16 | }>, description?: string): Promise;
17 | /**
18 | * Retrieves a registered model by name.
19 | *
20 | * @param {string} name - The name of the registered model to retrieve (required)
21 | * @returns {Promise} The registered model object
22 | * @throws {ApiError} If the API request fails
23 | */
24 | getRegisteredModel(name: string): Promise;
25 | /**
26 | * Renames a registered model.
27 | *
28 | * @param {string} name - The current name of the registered model (required)
29 | * @param {string} newName - The new name for the registered model (required)
30 | * @returns {Promise} The updated registered model object
31 | * @throws {ApiError} If the API request fails
32 | */
33 | renameRegisteredModel(name: string, newName: string): Promise;
34 | /**
35 | * Updates a registered model's description.
36 | *
37 | * @param {string} name - The name of the registered model to update (required)
38 | * @param {string} [description] - The new description for the model
39 | * @returns {Promise} The updated registered model object
40 | * @throws {ApiError} If the API request fails
41 | */
42 | updateRegisteredModel(name: string, description?: string): Promise;
43 | /**
44 | * Deletes a registered model.
45 | *
46 | * @param {string} name - The name of the registered model to delete (required)
47 | * @returns {Promise}
48 | * @throws {ApiError} If the API request fails
49 | */
50 | deleteRegisteredModel(name: string): Promise;
51 | /**
52 | * Gets the latest versions of a registered model.
53 | *
54 | * @param {string} name - The name of the registered model (required)
55 | * @param {string[]} [stages] - Optional array of stages to filter the versions by
56 | * @returns {Promise} An array of the latest model versions
57 | * @throws {ApiError} If the API request fails
58 | */
59 | getLatestModelVersions(name: string, stages?: string[]): Promise>;
60 | /**
61 | * Searches for registered models based on filter criteria.
62 | *
63 | * @param {string} [filter] - Optional filter string to apply to the search
64 | * @param {number} [maxResults] - Optional maximum number of results to return
65 | * @param {string[]} [orderBy] - Optional array of fields to order the results by
66 | * @param {string} [pageToken] - Optional token for pagination
67 | * @returns {Promise<{registered_models: RegisteredModel[], next_page_token: string}>} An object containing the search results and pagination information
68 | * @throws {ApiError} If the API request fails
69 | */
70 | searchRegisteredModels(filter?: string, maxResults?: number, orderBy?: string[], pageToken?: string): Promise;
71 | /**
72 | * Sets a tag on a registered model.
73 | *
74 | * @param {string} name - The name of the registered model (required)
75 | * @param {string} key - The key of the tag (required)
76 | * @param {string} value - The value of the tag (required)
77 | * @returns {Promise}
78 | * @throws {ApiError} If the API request fails
79 | */
80 | setRegisteredModelTag(name: string, key: string, value: string): Promise;
81 | /**
82 | * Deletes a tag from a registered model.
83 | *
84 | * @param {string} name - The name of the registered model (required)
85 | * @param {string} key - The key of the tag to delete (required)
86 | * @returns {Promise}
87 | * @throws {ApiError} If the API request fails
88 | */
89 | deleteRegisteredModelTag(name: string, key: string): Promise;
90 | /**
91 | * Sets an alias for a specific version of a registered model.
92 | *
93 | * @param {string} name - The name of the registered model (required)
94 | * @param {string} alias - The alias to set (required)
95 | * @param {string} version - The version number to associate with the alias (required)
96 | * @returns {Promise}
97 | * @throws {ApiError} If the API request fails
98 | */
99 | setRegisteredModelAlias(name: string, alias: string, version: string): Promise;
100 | /**
101 | * Deletes an alias from a registered model.
102 | *
103 | * @param {string} name - The name of the registered model (required)
104 | * @param {string} alias - The alias to delete (required)
105 | * @returns {Promise}
106 | * @throws {ApiError} If the API request fails
107 | */
108 | deleteRegisteredModelAlias(name: string, alias: string): Promise;
109 | /**
110 | * Retrieves a model version using its alias.
111 | *
112 | * @param {string} name - The name of the registered model (required)
113 | * @param {string} alias - The alias of the model version to retrieve (required)
114 | * @returns {Promise} The model version object
115 | * @throws {ApiError} If the API request fails
116 | */
117 | getModelVersionByAlias(name: string, alias: string): Promise;
118 | }
119 | export default ModelRegistryClient;
120 |
--------------------------------------------------------------------------------
/mlflow/lib/model-registry/ModelRegistryClient.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ModelRegistryClient.js","sourceRoot":"","sources":["../../src/model-registry/ModelRegistryClient.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/model-registry/ModelVersionClient.d.ts:
--------------------------------------------------------------------------------
1 | declare class ModelVersionClient {
2 | private baseUrl;
3 | constructor(trackingUri: string);
4 | /**
5 | * Creates a new version of a model
6 | *
7 | * @param {string} modelName - the name of the registered model (required)
8 | * @param {string} source - the source path where the model artifacts are stored (required)
9 | * @param {string} run_id - the id of the run that generated this version (optional)
10 | * @param {string[]} tags - Tag of key/value pairs for the model version (optional)
11 | * @param {string} run_link - MLflow run link - the exact link of the run that generated this
12 | * model version (optional)
13 | * @param {string} description - Description of the model version (optional)
14 | * @returns {Promise} - the created model version object
15 | * @throws {ApiError} If the API request fails
16 | */
17 | createModelVersion(modelName: string, source: string, run_id?: string, tags?: Array<{
18 | key: string;
19 | value: string;
20 | }>, run_link?: string, description?: string): Promise;
21 | /**
22 | * Gets the specified version of the model
23 | *
24 | * @param {string} modelName - the name of the registered model (Required)
25 | * @param {string} version - the version number of the model to fetch (Required)
26 | * @returns {Promise} - the created model version object
27 | * @throws {ApiError} If the API request fails
28 | */
29 | getModelVersion(modelName: string, version: string): Promise;
30 | /**
31 | * Updates a specific model version.
32 | *
33 | * @param {string} modelName - the name of the registered model (Required)
34 | * @param {string} version - the version number of the model to update (Required)
35 | * @param {string} description - The description of the model version (Optional)
36 | * @returns {Promise} - the created model version object
37 | * @throws {ApiError} If the API request fails
38 | */
39 | updateModelVersion(modelName: string, version: string, description?: string): Promise;
40 | /**
41 | * Searches for model versions based on provided filters.
42 | *
43 | * @param {string} filter - the filter criteria for searching model versions (Optional)
44 | * @param {number} maxResults - the maximum number of results to return (Optional)
45 | * @param {string[]} order_by - List of columns to be ordered by (Optional)
46 | * @param {string} page_token - Pagination token to go to next page based on previous search query (Optional)
47 | * @returns {Promise} - an array of model versions that match the search criteria
48 | * @throws {ApiError} If the API request fails
49 | */
50 | searchModelVersions(filter?: string, maxResults?: number, order_by?: Array, page_token?: string): Promise>;
51 | /**
52 | * Retrieves the download uri for model version artifacts.
53 | *
54 | * @param {string} modelName - the name of the registered model (Required)
55 | * @param {string} version - the version number of the model to fetch the uri for (Required)
56 | * @returns {Promise} - the uri for downloading the model version artifacts
57 | * @throws {ApiError} If the API request fails
58 | */
59 | getDownloadUriForModelVersionArtifacts(modelName: string, version: string): Promise;
60 | /**
61 | * Transitions a model version to a different stage.
62 | *
63 | * @param {string} modelName - the name of the registered model (Required)
64 | * @param {string} version - the version number of the model to transition (Required)
65 | * @param {string} stage - the stage to transition the model version to (e.g., 'staging', 'production') (Required)
66 | * @param {boolean} archive_existing_versions - This flag dictates whether all existing model
67 | * versions in that stage should be atomically moved to the "archived" stage. This ensures
68 | * that at-most-one model version exists in the target stage. (Required)
69 | * @returns {Promise} - the updated model version object after the stage transition
70 | * @throws {ApiError} If the API request fails
71 | */
72 | transitionModelVersionStage(modelName: string, version: string, stage: string, archive_existing_versions: boolean): Promise;
73 | /**
74 | * Sets a tag on a specific model version.
75 | *
76 | * @param {string} modelName - the name of the registered model (required)
77 | * @param {string} version - the version number of the model to tag (required)
78 | * @param {string} key - the key of the tag (required)
79 | * @param {string} value - the value of the tag (required)
80 | * @returns {Promise}
81 | * @throws {ApiError} If the API request fails
82 | */
83 | setModelVersionTag(modelName: string, version: string, key: string, value: string): Promise;
84 | /**
85 | * Deletes a tag from a specific model version.
86 | *
87 | * @param {string} modelName - the name of the registered model (required)
88 | * @param {string} version - the version number of the model to untag (required)
89 | * @param {string} key - the key of the tag to delete (required)
90 | * @returns {Promise}
91 | * @throws {ApiError} If the API request fails
92 | */
93 | deleteModelVersionTag(modelName: string, version: string, key: string): Promise;
94 | /**
95 | * Deletes a specific model version.
96 | *
97 | * @param {string} modelName - the name of the registered model (Required)
98 | * @param {string} version - the version number of the model to delete (Required)
99 | * @returns {Promise}
100 | * @throws {ApiError} If the API request fails
101 | */
102 | deleteModelVersion(modelName: string, version: string): Promise;
103 | }
104 | export default ModelVersionClient;
105 |
--------------------------------------------------------------------------------
/mlflow/lib/model-registry/ModelVersionClient.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ModelVersionClient.js","sourceRoot":"","sources":["../../src/model-registry/ModelVersionClient.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/tracking/ExperimentClient.d.ts:
--------------------------------------------------------------------------------
1 | declare class ExperimentClient {
2 | trackingUri: string;
3 | constructor(trackingUri: string);
4 | /**
5 | * Create an experiment with a name. Returns the ID of the newly created experiment.
6 | * Validates that another experiment with the same name does not already exist and fails if another experiment with the same name already exists.
7 | *
8 | * @param {string} name Experiment name. (required)
9 | * @param {string} artifact_location Optional location where all artifacts for the experiment are stored. If not provided, the remote server will select an appropriate default.
10 | * @param {Array<{key: string, value: string}>} tags Optional collection of tags to set on the experiment.
11 | * @returns {Promise} Returns the ID of the newly created experiment in an object.
12 | * @throws {ApiError} If the API request fails
13 | */
14 | createExperiment(name: string, artifact_location?: string, tags?: Array<{
15 | key: string;
16 | value: string;
17 | }>): Promise;
18 | /**
19 | * Search experiments.
20 | *
21 | * @param {string} filter A filter expression over experiment attributes and tags that allows returning a subset of experiments. The syntax is a subset of SQL. (required)
22 | * @param {number} max_results Maximum number of experiments desired. (required)
23 | * @param {string} page_token Optional token indicating the page of experiments to fetch.
24 | * @param {string[]} order_by Optional list of columns for ordering search results.
25 | * @param {string} view_type Optional qualifier for type of experiments to be returned. See https://mlflow.org/docs/latest/rest-api.html#mlflowviewtype
26 | * @returns {Promise} Returns object containing an array of experiment objects matching the filter,
27 | * and optionally a next_page_token that can be used to retrieve the next page of experiments.
28 | * @throws {ApiError} If the API request fails
29 | */
30 | searchExperiment(filter: string, max_results: number, page_token?: string, order_by?: string[], view_type?: string): Promise;
31 | /**
32 | * Get metadata for an experiment, querying by experiment ID. This method works on deleted experiments.
33 | *
34 | * @param {string} experiment_id ID of the associated experiment. (required)
35 | * @returns {Promise} Returns object containing the matched experiment.
36 | * @throws {ApiError} If the API request fails
37 | */
38 | getExperiment(experiment_id: string): Promise;
39 | /**
40 | * Get metadata for an experiment, querying by experiment name.
41 | * This endpoint will return deleted experiments,
42 | * but prefers the active experiment if an active and deleted experiment share the same name.
43 | * If multiple deleted experiments share the same name, the API will return one of them.
44 | *
45 | * @param {string} experiment_name ID of the associated experiment. (required)
46 | * @returns {Promise} Returns object containing the matched experiment.
47 | * @throws {ApiError} If the API request fails
48 | */
49 | getExperimentByName(experiment_name: string): Promise;
50 | /**
51 | * Mark an experiment for deletion.
52 | *
53 | * @param {string} experiment_id ID of the associated experiment. (required)
54 | * @returns {Promise}
55 | * @throws {ApiError} If the API request fails
56 | */
57 | deleteExperiment(experiment_id: string): Promise;
58 | /**
59 | * Restore an experiment marked for deletion.
60 | *
61 | * @param {string} experiment_id ID of the associated experiment. (required)
62 | * @returns {Promise}
63 | * @throws {ApiError} If the API request fails
64 | */
65 | restoreExperiment(experiment_id: string): Promise;
66 | /**
67 | * Update experiment name.
68 | *
69 | * @param {string} experiment_id ID of the associated experiment. (required)
70 | * @param {string} new_name The experiment’s name is changed to the new name. The new name must be unique. (required)
71 | * @returns {Promise}
72 | * @throws {ApiError} If the API request fails
73 | */
74 | updateExperiment(experiment_id: string, new_name: string): Promise;
75 | /**
76 | * Set a tag on an experiment.
77 | *
78 | * @param {string} experiment_id ID of the experiment under which to log the tag. (required)
79 | * @param {string} key Name of the tag. (required)
80 | * @param {string} value String value of the tag being logged. (required)
81 | * @returns {Promise}
82 | * @throws {ApiError} If the API request fails
83 | */
84 | setExperimentTag(experiment_id: string, key: string, value: string): Promise;
85 | }
86 | export default ExperimentClient;
87 |
--------------------------------------------------------------------------------
/mlflow/lib/tracking/ExperimentClient.js:
--------------------------------------------------------------------------------
1 | import { ApiError } from '../utils/apiError.js';
2 | import { apiRequest } from '../utils/apiRequest.js';
3 | class ExperimentClient {
4 | constructor(trackingUri) {
5 | this.trackingUri = trackingUri;
6 | }
7 | /**
8 | * Create an experiment with a name. Returns the ID of the newly created experiment.
9 | * Validates that another experiment with the same name does not already exist and fails if another experiment with the same name already exists.
10 | *
11 | * @param {string} name Experiment name. (required)
12 | * @param {string} artifact_location Optional location where all artifacts for the experiment are stored. If not provided, the remote server will select an appropriate default.
13 | * @param {Array<{key: string, value: string}>} tags Optional collection of tags to set on the experiment.
14 | * @returns {Promise} Returns the ID of the newly created experiment in an object.
15 | * @throws {ApiError} If the API request fails
16 | */
17 | async createExperiment(name, artifact_location, tags) {
18 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/create', {
19 | method: 'POST',
20 | body: { name, artifact_location, tags },
21 | });
22 | if (!response.ok) {
23 | throw new ApiError(`Error creating experiment from tracking server: ${data.message || response.statusText}`, response.status);
24 | }
25 | return data.experiment_id;
26 | }
27 | /**
28 | * Search experiments.
29 | *
30 | * @param {string} filter A filter expression over experiment attributes and tags that allows returning a subset of experiments. The syntax is a subset of SQL. (required)
31 | * @param {number} max_results Maximum number of experiments desired. (required)
32 | * @param {string} page_token Optional token indicating the page of experiments to fetch.
33 | * @param {string[]} order_by Optional list of columns for ordering search results.
34 | * @param {string} view_type Optional qualifier for type of experiments to be returned. See https://mlflow.org/docs/latest/rest-api.html#mlflowviewtype
35 | * @returns {Promise} Returns object containing an array of experiment objects matching the filter,
36 | * and optionally a next_page_token that can be used to retrieve the next page of experiments.
37 | * @throws {ApiError} If the API request fails
38 | */
39 | async searchExperiment(filter, max_results, page_token, order_by, view_type) {
40 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/search', {
41 | method: 'POST',
42 | body: { filter, max_results, page_token, order_by, view_type },
43 | });
44 | if (!response.ok) {
45 | throw new ApiError(`Error searching for experiment from tracking server: ${data.message || response.statusText}`, response.status);
46 | }
47 | return data;
48 | }
49 | /**
50 | * Get metadata for an experiment, querying by experiment ID. This method works on deleted experiments.
51 | *
52 | * @param {string} experiment_id ID of the associated experiment. (required)
53 | * @returns {Promise} Returns object containing the matched experiment.
54 | * @throws {ApiError} If the API request fails
55 | */
56 | async getExperiment(experiment_id) {
57 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/get', {
58 | method: 'GET',
59 | params: { experiment_id }
60 | });
61 | if (!response.ok) {
62 | throw new ApiError(`Error getting experiment from tracking server: ${data.message || response.statusText}`, response.status);
63 | }
64 | return data.experiment;
65 | }
66 | /**
67 | * Get metadata for an experiment, querying by experiment name.
68 | * This endpoint will return deleted experiments,
69 | * but prefers the active experiment if an active and deleted experiment share the same name.
70 | * If multiple deleted experiments share the same name, the API will return one of them.
71 | *
72 | * @param {string} experiment_name ID of the associated experiment. (required)
73 | * @returns {Promise} Returns object containing the matched experiment.
74 | * @throws {ApiError} If the API request fails
75 | */
76 | async getExperimentByName(experiment_name) {
77 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/get-by-name', {
78 | method: 'GET',
79 | params: { experiment_name }
80 | });
81 | if (!response.ok) {
82 | throw new ApiError(`Error getting experiment by name from tracking server: ${data.message || response.statusText}`, response.status);
83 | }
84 | return data.experiment;
85 | }
86 | /**
87 | * Mark an experiment for deletion.
88 | *
89 | * @param {string} experiment_id ID of the associated experiment. (required)
90 | * @returns {Promise}
91 | * @throws {ApiError} If the API request fails
92 | */
93 | async deleteExperiment(experiment_id) {
94 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/delete', {
95 | method: 'POST',
96 | body: { experiment_id },
97 | });
98 | if (!response.ok) {
99 | throw new ApiError(`Error deleting experiment from tracking server: ${data.message || response.statusText}`, response.status);
100 | }
101 | ;
102 | console.log(`Experiment ID ${experiment_id} successfully deleted`);
103 | }
104 | /**
105 | * Restore an experiment marked for deletion.
106 | *
107 | * @param {string} experiment_id ID of the associated experiment. (required)
108 | * @returns {Promise}
109 | * @throws {ApiError} If the API request fails
110 | */
111 | async restoreExperiment(experiment_id) {
112 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/restore', {
113 | method: 'POST',
114 | body: { experiment_id },
115 | });
116 | if (!response.ok) {
117 | throw new ApiError(`Error restoring experiment from tracking server: ${data.message || response.statusText}`, response.status);
118 | }
119 | console.log(`Experiment ID ${experiment_id} successfully restored`);
120 | }
121 | /**
122 | * Update experiment name.
123 | *
124 | * @param {string} experiment_id ID of the associated experiment. (required)
125 | * @param {string} new_name The experiment’s name is changed to the new name. The new name must be unique. (required)
126 | * @returns {Promise}
127 | * @throws {ApiError} If the API request fails
128 | */
129 | async updateExperiment(experiment_id, new_name) {
130 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/update', {
131 | method: 'POST',
132 | body: { experiment_id, new_name },
133 | });
134 | if (!response.ok) {
135 | throw new ApiError(`Error updating experiment from tracking server: ${data.message || response.statusText}`, response.status);
136 | }
137 | console.log(`Experiment ID ${experiment_id} successfully updated - new name is ${new_name}`);
138 | }
139 | /**
140 | * Set a tag on an experiment.
141 | *
142 | * @param {string} experiment_id ID of the experiment under which to log the tag. (required)
143 | * @param {string} key Name of the tag. (required)
144 | * @param {string} value String value of the tag being logged. (required)
145 | * @returns {Promise}
146 | * @throws {ApiError} If the API request fails
147 | */
148 | async setExperimentTag(experiment_id, key, value) {
149 | const { response, data } = await apiRequest(this.trackingUri, 'experiments/set-experiment-tag', {
150 | method: 'POST',
151 | body: { experiment_id, key, value },
152 | });
153 | if (!response.ok) {
154 | throw new ApiError(`Error setting tag from tracking server: ${data.message || response.statusText}`, response.status);
155 | }
156 | console.log(`Set tag to experiment ID ${experiment_id} successfully`);
157 | }
158 | }
159 | export default ExperimentClient;
160 | //# sourceMappingURL=ExperimentClient.js.map
--------------------------------------------------------------------------------
/mlflow/lib/tracking/ExperimentClient.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ExperimentClient.js","sourceRoot":"","sources":["../../src/tracking/ExperimentClient.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/tracking/RunClient.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"RunClient.js","sourceRoot":"","sources":["../../src/tracking/RunClient.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiError.d.ts:
--------------------------------------------------------------------------------
1 | export declare class ApiError extends Error {
2 | statusCode: number;
3 | constructor(message: string, statusCode: number);
4 | }
5 |
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiError.js:
--------------------------------------------------------------------------------
1 | export class ApiError extends Error {
2 | constructor(message, statusCode) {
3 | super(message);
4 | this.name = 'ApiError';
5 | this.statusCode = statusCode;
6 | }
7 | }
8 | //# sourceMappingURL=apiError.js.map
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiError.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"apiError.js","sourceRoot":"","sources":["../../src/utils/apiError.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGjC,YAAY,OAAe,EAAE,UAAkB;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF"}
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiRequest.d.ts:
--------------------------------------------------------------------------------
1 | interface RequestOptions {
2 | method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3 | body?: Record;
4 | params?: Record;
5 | }
6 | interface ApiResponse {
7 | response: Response;
8 | data: T;
9 | }
10 | /**
11 | * Utility function for making API requests to the MLflow server.
12 | *
13 | * @param baseUrl - The base URL of the MLflow server
14 | * @param endpoint - The API endpoint
15 | * @param options - Request options
16 | * @returns A promise that resolves to the response and data
17 | */
18 | export declare function apiRequest(baseUrl: string, endpoint: string, options: RequestOptions): Promise>;
19 | export {};
20 |
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiRequest.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Utility function for making API requests to the MLflow server.
3 | *
4 | * @param baseUrl - The base URL of the MLflow server
5 | * @param endpoint - The API endpoint
6 | * @param options - Request options
7 | * @returns A promise that resolves to the response and data
8 | */
9 | export async function apiRequest(baseUrl, endpoint, options) {
10 | let url = `${baseUrl}/api/2.0/mlflow/${endpoint}`;
11 | const { method, body, params } = options;
12 | const fetchOptions = {
13 | method,
14 | headers: {
15 | 'Content-Type': 'application/json',
16 | },
17 | };
18 | if (body) {
19 | fetchOptions.body = JSON.stringify(body);
20 | }
21 | if (params) {
22 | const searchParams = new URLSearchParams(params);
23 | url += `?${searchParams.toString()}`;
24 | }
25 | const response = await fetch(url, fetchOptions);
26 | const data = (await response.json());
27 | return { response, data };
28 | }
29 | //# sourceMappingURL=apiRequest.js.map
--------------------------------------------------------------------------------
/mlflow/lib/utils/apiRequest.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"apiRequest.js","sourceRoot":"","sources":["../../src/utils/apiRequest.ts"],"names":[],"mappings":"AAWA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,QAAgB,EAChB,OAAuB;IAEvB,IAAI,GAAG,GAAG,GAAG,OAAO,mBAAmB,QAAQ,EAAE,CAAC;IAClD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEzC,MAAM,YAAY,GAAgB;QAChC,MAAM;QACN,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QACjD,GAAG,IAAI,IAAI,YAAY,CAAC,QAAQ,EAAE,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;IAE1C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC"}
--------------------------------------------------------------------------------
/mlflow/lib/utils/interface.d.ts:
--------------------------------------------------------------------------------
1 | export interface Run {
2 | info: RunInfo;
3 | data: RunData;
4 | inputs?: RunInputs;
5 | }
6 | interface RunInfo {
7 | run_id: string;
8 | run_name: string;
9 | experiment_id: string;
10 | status: 'RUNNING' | 'SCHEDULED' | 'FINISHED' | 'FAILED' | 'KILLED';
11 | start_time: number;
12 | end_time: number;
13 | artifact_uri: string;
14 | lifecycle_stage: string;
15 | }
16 | interface RunData {
17 | metrics: Metrics[];
18 | params: Params[];
19 | tags: Tags[];
20 | }
21 | interface RunInputs {
22 | dataset_inputs?: DatasetInput[];
23 | }
24 | interface DatasetInput {
25 | tags?: Tags[];
26 | dataset: {
27 | name: string;
28 | digest: string;
29 | source_type: string;
30 | source: string;
31 | schema?: string;
32 | profile?: string;
33 | };
34 | }
35 | export interface Metrics {
36 | key: string;
37 | value: number;
38 | timestamp: number;
39 | }
40 | export interface Params {
41 | key: string;
42 | value: string;
43 | }
44 | export interface Tags {
45 | key: string;
46 | value: string;
47 | }
48 | export interface MetricHistoryResponse {
49 | metrics: Metrics[];
50 | next_page_token?: string;
51 | }
52 | export interface SearchedRuns {
53 | runs: Run[];
54 | next_page_token?: string;
55 | }
56 | export interface CleanupRuns {
57 | deletedRuns: Run[];
58 | total: number;
59 | dryRun: boolean;
60 | }
61 | export interface CopyRun {
62 | originalRunId: string;
63 | newRunId: string;
64 | targetExperimentId: string;
65 | }
66 | export interface Experiment {
67 | experiment_id: string;
68 | name: string;
69 | artifact_location: string;
70 | lifecycle_stage: string;
71 | last_update_time: string;
72 | creation_time: string;
73 | }
74 | export {};
75 |
--------------------------------------------------------------------------------
/mlflow/lib/utils/interface.js:
--------------------------------------------------------------------------------
1 | export {};
2 | //# sourceMappingURL=interface.js.map
--------------------------------------------------------------------------------
/mlflow/lib/utils/interface.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/utils/interface.ts"],"names":[],"mappings":""}
--------------------------------------------------------------------------------
/mlflow/lib/workflows/ExperimentManager.d.ts:
--------------------------------------------------------------------------------
1 | declare class ExperimentManager {
2 | private experimentClient;
3 | private runClient;
4 | constructor(trackingUri: string);
5 | /**
6 | * Full workflow of creating, naming and starting a run under an existing experiment (referenced by ID),
7 | * logging metrics, params, and tags, logging the model, and finishing the run.
8 | *
9 | * @param {string} experiment_id ID of the experiment under which to log the run. (required)
10 | * @param {string} run_name Name of the run to be created and run (optional)
11 | * @param {Array<{key: string, value: number, timestamp: number, step?: number}>} [metrics] The metrics to log (up to 1000 metrics) (optional)
12 | * @param {Array<{key: string, value: string}>} [params] The params to log (up to 100 params) (optional)
13 | * @param {Array<{key: string, value: string}>} [tags] The tags to log (up to 100 tags) (optional)
14 | * @param {{artifact_path: string, flavors: Object, model_url: string, model_uuid: string, utc_time_created: number, mlflow_version: string}} model The ML model data to log to the run, represented as a Javascript object (optional)
15 | * @returns {Promise} The created run object with updated metadata
16 | */
17 | runExistingExperiment(experiment_id: string, run_name?: string, metrics?: Array<{
18 | key: string;
19 | value: number;
20 | timestamp: number;
21 | step?: number;
22 | }>, params?: Array<{
23 | key: string;
24 | value: string;
25 | }>, tags?: Array<{
26 | key: string;
27 | value: string;
28 | }>, model?: {
29 | artifact_path: string;
30 | flavors: object;
31 | model_url: string;
32 | model_uuid: string;
33 | utc_time_created: number;
34 | mlflow_version: string;
35 | run_id?: string;
36 | }): Promise;
37 | /**
38 | * Full workflow of creating, naming and starting a run under a new experiment,
39 | * logging metrics, params, and tags, logging the model, and finishing the run.
40 | *
41 | * @param {string} experiment_name Name of the experiment under which to log the run. (required)
42 | * @param {string} run_name Name of the run to be created and run (optional)
43 | * @param {Array<{key: string, value: number, timestamp: number, step?: number}>} [metrics] The metrics to log (up to 1000 metrics) (optional)
44 | * @param {Array<{key: string, value: string}>} [params] The params to log (up to 100 params) (optional)
45 | * @param {Array<{key: string, value: string}>} [tags] The tags to log (up to 100 tags) (optional)
46 | * @param {Object} model The ML model data to log to the run, represented as a Javascript object (optional)
47 | * @returns {Promise} The created run object with updated metadata
48 | */
49 | runNewExperiment(experiment_name: string, run_name?: string, metrics?: Array<{
50 | key: string;
51 | value: number;
52 | timestamp: number;
53 | step?: number;
54 | }>, params?: Array<{
55 | key: string;
56 | value: string;
57 | }>, tags?: Array<{
58 | key: string;
59 | value: string;
60 | }>, model?: {
61 | artifact_path: string;
62 | flavors: object;
63 | model_url: string;
64 | model_uuid: string;
65 | utc_time_created: number;
66 | mlflow_version: string;
67 | run_id?: string;
68 | }): Promise;
69 | /**
70 | * Returns an array of all the passed-in experiment's runs, sorted according to the passed-in metric
71 | *
72 | * @param {string} experiment_id The experiment whose runs will be evaluated (required)
73 | * @param {string} primaryMetric The metric by which the results array will be sorted (required)
74 | * @param {string | number} order Sort order for the array: pass in 'DESC' or 1 for descending; 'ASC' or -1 for ascending
75 | * @returns {Promise>} An array of run objects belonging to the passed-in experiment ID, sorted according to the primary metric
76 | */
77 | experimentSummary(experiment_id: string, primaryMetric: string, order?: 'ASC' | 'DESC' | 1 | -1): Promise>;
78 | }
79 | export default ExperimentManager;
80 |
--------------------------------------------------------------------------------
/mlflow/lib/workflows/ExperimentManager.js:
--------------------------------------------------------------------------------
1 | import ExperimentClient from '../tracking/ExperimentClient.js';
2 | import RunClient from '../tracking/RunClient.js';
3 | import { ApiError } from '../utils/apiError.js';
4 | class ExperimentManager {
5 | constructor(trackingUri) {
6 | this.experimentClient = new ExperimentClient(trackingUri);
7 | this.runClient = new RunClient(trackingUri);
8 | }
9 | /**
10 | * Full workflow of creating, naming and starting a run under an existing experiment (referenced by ID),
11 | * logging metrics, params, and tags, logging the model, and finishing the run.
12 | *
13 | * @param {string} experiment_id ID of the experiment under which to log the run. (required)
14 | * @param {string} run_name Name of the run to be created and run (optional)
15 | * @param {Array<{key: string, value: number, timestamp: number, step?: number}>} [metrics] The metrics to log (up to 1000 metrics) (optional)
16 | * @param {Array<{key: string, value: string}>} [params] The params to log (up to 100 params) (optional)
17 | * @param {Array<{key: string, value: string}>} [tags] The tags to log (up to 100 tags) (optional)
18 | * @param {{artifact_path: string, flavors: Object, model_url: string, model_uuid: string, utc_time_created: number, mlflow_version: string}} model The ML model data to log to the run, represented as a Javascript object (optional)
19 | * @returns {Promise} The created run object with updated metadata
20 | */
21 | async runExistingExperiment(experiment_id, run_name, metrics, params, tags, model) {
22 | try {
23 | // create run
24 | const run = await this.runClient.createRun(experiment_id, run_name);
25 | const run_id = run.info.run_id;
26 | // log metric, params, and tags via logBatch
27 | await this.runClient.logBatch(run_id, metrics, params, tags);
28 | // log model
29 | // (model gets passed in as a JS object, not JSON - it gets JSON stringified here after adding a run_id property)
30 | if (model) {
31 | model.run_id = run_id;
32 | const model_json = JSON.stringify(model);
33 | await this.runClient.logModel(run_id, model_json);
34 | }
35 | // updateRun to finish it
36 | const latestRun = await this.runClient.updateRun(run_id, 'FINISHED');
37 | return latestRun.run_info;
38 | }
39 | catch (error) {
40 | if (error instanceof ApiError) {
41 | console.error(`API Error (${error.statusCode}): ${error.message}`);
42 | throw error;
43 | }
44 | else {
45 | console.error('An unexpected error occurred:', error);
46 | throw new Error();
47 | }
48 | }
49 | }
50 | /**
51 | * Full workflow of creating, naming and starting a run under a new experiment,
52 | * logging metrics, params, and tags, logging the model, and finishing the run.
53 | *
54 | * @param {string} experiment_name Name of the experiment under which to log the run. (required)
55 | * @param {string} run_name Name of the run to be created and run (optional)
56 | * @param {Array<{key: string, value: number, timestamp: number, step?: number}>} [metrics] The metrics to log (up to 1000 metrics) (optional)
57 | * @param {Array<{key: string, value: string}>} [params] The params to log (up to 100 params) (optional)
58 | * @param {Array<{key: string, value: string}>} [tags] The tags to log (up to 100 tags) (optional)
59 | * @param {Object} model The ML model data to log to the run, represented as a Javascript object (optional)
60 | * @returns {Promise} The created run object with updated metadata
61 | */
62 | async runNewExperiment(experiment_name, run_name, metrics, params, tags, model) {
63 | try {
64 | const experiment_id = await this.experimentClient.createExperiment(experiment_name);
65 | // create run
66 | const run = await this.runClient.createRun(experiment_id, run_name);
67 | const run_id = run.info.run_id;
68 | // log metric, params, and tags via logBatch
69 | await this.runClient.logBatch(run_id, metrics, params, tags);
70 | // log model
71 | // (model gets passed in as a JS object, not JSON - it gets JSON stringified here after adding a run_id property)
72 | if (model) {
73 | model.run_id = run_id;
74 | const model_json = JSON.stringify(model);
75 | await this.runClient.logModel(run_id, model_json);
76 | }
77 | // updateRun to finish it
78 | const latestRun = await this.runClient.updateRun(run_id, 'FINISHED');
79 | return latestRun.run_info;
80 | }
81 | catch (error) {
82 | if (error instanceof ApiError) {
83 | console.error(`API Error (${error.statusCode}): ${error.message}`);
84 | throw error;
85 | }
86 | else {
87 | console.error('An unexpected error occurred:', error);
88 | throw new Error();
89 | }
90 | }
91 | }
92 | /**
93 | * Returns an array of all the passed-in experiment's runs, sorted according to the passed-in metric
94 | *
95 | * @param {string} experiment_id The experiment whose runs will be evaluated (required)
96 | * @param {string} primaryMetric The metric by which the results array will be sorted (required)
97 | * @param {string | number} order Sort order for the array: pass in 'DESC' or 1 for descending; 'ASC' or -1 for ascending
98 | * @returns {Promise>} An array of run objects belonging to the passed-in experiment ID, sorted according to the primary metric
99 | */
100 | async experimentSummary(experiment_id, primaryMetric, order) {
101 | try {
102 | // use Search Runs to return all runs whose experiment ID matches the passed in one
103 | // use Search Runs's order_by field to sort results array by primaryMetric
104 | let orderString;
105 | if (order === 1 || order === 'DESC')
106 | orderString = 'DESC';
107 | else if (order === -1 || order === 'ASC')
108 | orderString = 'ASC';
109 | const arg = `metrics.${primaryMetric} ${orderString}`;
110 | const data = await this.runClient.searchRuns([experiment_id], '', undefined, undefined, [arg]);
111 | data.runs.forEach((el) => {
112 | const arr = el.data.metrics;
113 | let val;
114 | arr.forEach((obj) => {
115 | if (obj.key === primaryMetric)
116 | val = obj.value;
117 | });
118 | el[primaryMetric] = val;
119 | });
120 | return data.runs;
121 | }
122 | catch (error) {
123 | if (error instanceof ApiError) {
124 | console.error(`API Error (${error.statusCode}): ${error.message}`);
125 | throw error;
126 | }
127 | else {
128 | console.error('An unexpected error occurred:', error);
129 | throw new Error();
130 | }
131 | }
132 | }
133 | }
134 | export default ExperimentManager;
135 | //# sourceMappingURL=ExperimentManager.js.map
--------------------------------------------------------------------------------
/mlflow/lib/workflows/ExperimentManager.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ExperimentManager.js","sourceRoot":"","sources":["../../src/workflows/ExperimentManager.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/workflows/ModelManager.d.ts:
--------------------------------------------------------------------------------
1 | declare class ModelManager {
2 | private modelRegistry;
3 | private modelVersion;
4 | private runClient;
5 | constructor(trackingUri: string);
6 | /**
7 | * Creates a new registered model and creates the first version of that model.
8 | *
9 | * @param {string} name - Name of the registered model. (Required)
10 | * @param {string} versionSource - URI indicating the location of the model artifacts. (Required)
11 | * @param {string} versionRun_id - MLflow run ID for correlation, if versionSource was generated
12 | * by an experiment run in MLflow tracking server.
13 | * @returns {Promise} - the updated model version object
14 | * @throws {ApiError | Error} If request fails
15 | */
16 | createRegisteredModelWithVersion(name: string, versionSource: string, versionRun_id: string): Promise;
17 | /**
18 | * Updates a registered model's description and tag.
19 | *
20 | * @param {string} name - Name of the registered model. (Required)
21 | * @param {string} tagKey - Name of the tag. (Required)
22 | * @param {string} tagValue - String value of the tag being logged. (Required)
23 | * @param {string} description - Description of the registered model.
24 | * @returns {Promise} - the updated registered model object
25 | * @throws {ApiError | Error} If request fails
26 | */
27 | updateRegisteredModelDescriptionAndTag(name: string, tagKey: string, tagValue: string, description: string): Promise;
28 | /**
29 | * Updates the latest version of the specified registered model's description.
30 | * And adds a new alias, and tag key/value for that latest version.
31 | *
32 | * @param {string} name - Name of the registered model. (Required)
33 | * @param {string} alias - Name of the alias. (Required)
34 | * @param {string} description - The description for the model version. (Required)
35 | * @param {string} key - Name of the tag. (Required)
36 | * @param {string} value - Name of the value of the tag being logged. (Required)
37 | * @returns {Promise} - the updated model version object
38 | * @throws {ApiError | Error} If request fails
39 | */
40 | updateAllLatestModelVersion(name: string, alias: string, description: string, key: string, value: string): Promise;
41 | /**
42 | * Adds a new tag key/value for the latest version of the specified registered model.
43 | *
44 | * @param {string} name - Name of the registered model. (Required)
45 | * @param {string} key - Name of the tag. (Required)
46 | * @param {string} value - Name of the value of the tag being logged. (Required)
47 | * @returns {Promise} - a promise that resolves when the model version is deleted
48 | * @throws {ApiError | Error} If request fails
49 | */
50 | setLatestModelVersionTag(name: string, key: string, value: string): Promise;
51 | /**
52 | * Adds an alias for the latest version of the specified registered model.
53 | *
54 | * @param {string} name - Name of the registered model. (Required)
55 | * @param {string} alias - Name of the alias. (Required)
56 | * @returns {Promise} - a promise that resolves when the model version is deleted
57 | * @throws {ApiError | Error} If request fails
58 | */
59 | setLatestModelVersionAlias(name: string, alias: string): Promise;
60 | /**
61 | * Updates the description of the latest version of a registered model.
62 | *
63 | * @param {string} name - Name of the registered model. (Required)
64 | * @param {string} description - The description for the model version. (Required)
65 | * @returns {Promise} - the updated model version object
66 | * @throws {ApiError | Error} If request fails
67 | */
68 | updateLatestModelVersion(name: string, description: string): Promise;
69 | /**
70 | * Updates the specified version of the specified registered model's description.
71 | * And adds a new alias, and tag key/value for that specified version.
72 | *
73 | * @param {string} name - Name of the registered model. (Required)
74 | * @param {string} version - Model version number. (Required)
75 | * @param {string} alias - Name of the alias. (Required)
76 | * @param {string} key key - Name of the tag. (Required)
77 | * @param {string} value - Name of the value of the tag being logged. (Required)
78 | * @param {string} description - The description for the model version. (Required)
79 | * @returns {Promise} - the updated model version object
80 | * @throws {ApiError | Error} If request fails
81 | */
82 | updateAllModelVersion(name: string, version: string, alias: string, key: string, value: string, description: string): Promise;
83 | /**
84 | * Deletes the latest version of the specified registered model.
85 | *
86 | * @param {string} name - the model name
87 | * @returns - a promise that resolves when the model version is deleted
88 | * @throws {ApiError | Error} If request fails
89 | */
90 | deleteLatestModelVersion(name: string): Promise;
91 | /**
92 | * Looks through the runs with the given experiment id and through their metrics
93 | * looking for the specified metric that has the highest or lowest value (can be specified).
94 | * Then it creates a new model with the specified model name and creates a version of that
95 | * model from the run with the best metric.
96 | *
97 | * @param {string[]} experiment_ids - An array containing an experiment id. (Required)
98 | * @param {string} filterMetric - The name of the metric that we're filtering by. (Required)
99 | * @param {string} metricMinOrMax - A string specifying if we want the minimum or maximum
100 | * value of the specified metric. Can be either 'min' or
101 | * 'max'(Required)
102 | * @param {string} modelName - The name of the new model that will be created. (Required)
103 | * @returns {Promise}
104 | * @throws {ApiError | Error} If request fails
105 | */
106 | createModelFromRunWithBestMetric(experiment_ids: string[], filterMetric: string, metricMinOrMax: string, modelName: string): Promise;
107 | }
108 | export default ModelManager;
109 |
--------------------------------------------------------------------------------
/mlflow/lib/workflows/ModelManager.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"ModelManager.js","sourceRoot":"","sources":["../../src/workflows/ModelManager.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/lib/workflows/RunManager.d.ts:
--------------------------------------------------------------------------------
1 | declare class RunManager {
2 | private runClient;
3 | private modelVersion;
4 | constructor(trackingUri: string);
5 | /**
6 | * Delete runs that do not meet certain criteria and return deleted runs.
7 | * Dry run is set to true by default. To delete, set dry run to false.
8 | *
9 | * @param {Array} [experiment_ids] - The IDs of the associated experiments. (required)
10 | * @param {string} query_string - SQL-like query string to filter runs to keep. (required)
11 | * @param {string} metric_key - The metric key for comparison. (required)
12 | * @param {boolean} [dryRun=true] - If true, only simulate the deletion. Defaults to true. (optional)
13 | * @returns {Promise} - An object of deleted runs.
14 | */
15 | cleanupRuns(experiment_ids: Array, query_string: string, metric_key: string, dryRun?: boolean): Promise;
16 | /**
17 | * Copy run from one experiment to another without artifactss and models.
18 | * Artifacts and models detail tagged in new run as reference.
19 | *
20 | * @param {string} run_id - The ID of the run to be copied. (required)
21 | * @param {string} target_experiment_id - The ID of the target experiment. (required)
22 | * @param {string} run_name - The name of the new run in target experiment. (optional)
23 | * @returns {Promise} - An object detail of the copied run.
24 | */
25 | copyRun(run_id: string, target_experiment_id: string, run_name?: null): Promise;
26 | }
27 | export default RunManager;
28 |
--------------------------------------------------------------------------------
/mlflow/lib/workflows/RunManager.js:
--------------------------------------------------------------------------------
1 | import RunClient from '../tracking/RunClient.js';
2 | import ModelVersionClient from '../model-registry/ModelVersionClient.js';
3 | import { ApiError } from '../utils/apiError.js';
4 | class RunManager {
5 | constructor(trackingUri) {
6 | this.runClient = new RunClient(trackingUri);
7 | this.modelVersion = new ModelVersionClient(trackingUri);
8 | }
9 | /**
10 | * Delete runs that do not meet certain criteria and return deleted runs.
11 | * Dry run is set to true by default. To delete, set dry run to false.
12 | *
13 | * @param {Array} [experiment_ids] - The IDs of the associated experiments. (required)
14 | * @param {string} query_string - SQL-like query string to filter runs to keep. (required)
15 | * @param {string} metric_key - The metric key for comparison. (required)
16 | * @param {boolean} [dryRun=true] - If true, only simulate the deletion. Defaults to true. (optional)
17 | * @returns {Promise} - An object of deleted runs.
18 | */
19 | async cleanupRuns(experiment_ids, query_string, metric_key, dryRun = true) {
20 | var _a;
21 | const deletedRuns = [];
22 | const keepRunIds = new Set();
23 | const runViewType = undefined;
24 | let pageToken = undefined;
25 | const maxResults = 1000;
26 | try {
27 | do {
28 | // get all runs
29 | const searchResult = (await this.runClient.searchRuns(experiment_ids, '', runViewType, maxResults, ['start_time DESC'], pageToken));
30 | // get runs that match the keep crteria
31 | const keepRunsResult = (await this.runClient.searchRuns(experiment_ids, query_string, runViewType, maxResults, ['start_time DESC'], pageToken));
32 | // Add runs from keepRunsResult to keepResult
33 | (_a = keepRunsResult.runs) === null || _a === void 0 ? void 0 : _a.forEach((run) => keepRunIds.add(run.info.run_id));
34 | // Process each run
35 | for (const run of searchResult.runs) {
36 | const metrics = run.data.metrics;
37 | const hasMetricKey = Array.isArray(metrics)
38 | ? metrics.some((metric) => metric.key === metric_key)
39 | : metric_key in metrics;
40 | if (!hasMetricKey || keepRunIds.has(run.info.run_id)) {
41 | keepRunIds.add(run.info.run_id);
42 | }
43 | else {
44 | deletedRuns.push(run);
45 | if (!dryRun) {
46 | await this.runClient.deleteRun(run.info.run_id);
47 | }
48 | }
49 | }
50 | pageToken = searchResult.next_page_token;
51 | } while (pageToken);
52 | return {
53 | deletedRuns: deletedRuns,
54 | total: deletedRuns.length,
55 | dryRun,
56 | };
57 | }
58 | catch (error) {
59 | if (error instanceof ApiError) {
60 | console.error(`API Error (${error.statusCode}): ${error.message}`);
61 | }
62 | else {
63 | console.error('An unexpected error occurred: ', error);
64 | }
65 | throw error;
66 | }
67 | }
68 | /**
69 | * Copy run from one experiment to another without artifactss and models.
70 | * Artifacts and models detail tagged in new run as reference.
71 | *
72 | * @param {string} run_id - The ID of the run to be copied. (required)
73 | * @param {string} target_experiment_id - The ID of the target experiment. (required)
74 | * @param {string} run_name - The name of the new run in target experiment. (optional)
75 | * @returns {Promise} - An object detail of the copied run.
76 | */
77 | async copyRun(run_id, target_experiment_id, run_name = null) {
78 | try {
79 | // get original run
80 | const originalRun = (await this.runClient.getRun(run_id));
81 | // create a new run in the target experiment
82 | const newRun = (await this.runClient.createRun(target_experiment_id, undefined, originalRun.info.start_time));
83 | const newRunId = newRun.info.run_id;
84 | const endTime = originalRun.info.end_time || undefined;
85 | // copy run information
86 | await this.runClient.updateRun(newRunId, originalRun.info.status, endTime);
87 | if (originalRun.info.lifecycle_stage !== 'active') {
88 | await this.runClient.setTag(newRunId, 'mlflow.lifecycleStage', originalRun.info.lifecycle_stage);
89 | }
90 | // copy parameters
91 | if (originalRun.data.params) {
92 | for (const param of originalRun.data.params) {
93 | await this.runClient.logParam(newRunId, param.key, param.value);
94 | }
95 | }
96 | // copy metrics
97 | if (originalRun.data.metrics) {
98 | for (const metric of originalRun.data.metrics) {
99 | await this.runClient.logMetric(newRunId, metric.key, metric.value);
100 | }
101 | }
102 | // copy tags
103 | if (originalRun.data.tags) {
104 | for (const tag of originalRun.data.tags) {
105 | await this.runClient.setTag(newRunId, tag.key, tag.value);
106 | }
107 | }
108 | // copy inputs
109 | if (originalRun.inputs &&
110 | originalRun.inputs.dataset_inputs &&
111 | originalRun.inputs.dataset_inputs.length > 0) {
112 | // Log each dataset input separately
113 | for (const datasetInput of originalRun.inputs.dataset_inputs) {
114 | await this.runClient.logInputs(newRunId, [datasetInput]);
115 | }
116 | }
117 | // update the new run name
118 | if (run_name) {
119 | await this.runClient.setTag(newRunId, 'mlflow.runName', run_name);
120 | }
121 | // handle models (reference only)
122 | const modelVersions = await this.modelVersion.searchModelVersions(`run_id = '${run_id}'`);
123 | if (modelVersions && modelVersions.length > 0) {
124 | for (const model of modelVersions) {
125 | if (typeof model === 'object' &&
126 | model !== null &&
127 | 'name' in model &&
128 | 'version' in model &&
129 | 'current_stage' in model &&
130 | 'source' in model) {
131 | await this.runClient.setTag(newRunId, `original_model_${model.name}`, JSON.stringify({
132 | name: model.name,
133 | version: model.version,
134 | current_stage: model.current_stage,
135 | source: model.source,
136 | }));
137 | }
138 | }
139 | await this.runClient.setTag(newRunId, 'mlflow.note.models', 'Models not copied, see original run.');
140 | }
141 | // set description for the new run
142 | const description = `This run was copied from experiment ${originalRun.info.experiment_id}, original run ID: ${run_id}. ` +
143 | `Original artifact URI: ${originalRun.info.artifact_uri}.`;
144 | await this.runClient.setTag(newRunId, 'mlflow.note.content', description);
145 | // set additional tags for the new run
146 | await this.runClient.setTag(newRunId, 'mlflow.source.run_id', run_id);
147 | await this.runClient.setTag(newRunId, 'mlflow.source.experiment_id', originalRun.info.experiment_id);
148 | await this.runClient.setTag(newRunId, 'mlflow.note.artifacts', 'Artifacts not copied - reference original run');
149 | // return copy run details
150 | return {
151 | originalRunId: run_id,
152 | newRunId: newRunId,
153 | targetExperimentId: target_experiment_id,
154 | };
155 | }
156 | catch (error) {
157 | if (error instanceof ApiError) {
158 | console.error(`API Error (${error.statusCode}): ${error.message}`);
159 | }
160 | else {
161 | console.error('An unexpected error occurred: ', error);
162 | }
163 | throw error;
164 | }
165 | }
166 | }
167 | export default RunManager;
168 | //# sourceMappingURL=RunManager.js.map
--------------------------------------------------------------------------------
/mlflow/lib/workflows/RunManager.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"RunManager.js","sourceRoot":"","sources":["../../src/workflows/RunManager.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/mlflow/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mlflow-js",
3 | "version": "1.0.1",
4 | "description": "JavaScript library for MLflow",
5 | "homepage": "https://www.mlflow-js.org/",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/oslabs-beta/mlflow-js.git"
9 | },
10 | "bugs": {
11 | "url": "https://github.com/oslabs-beta/mlflow-js/issues"
12 | },
13 | "pull_request": {
14 | "url": "https://github.com/oslabs-beta/mlflow-js/pulls"
15 | },
16 | "type": "module",
17 | "main": "lib/index.js",
18 | "types": "lib/index.d.ts",
19 | "files": [
20 | "lib/",
21 | "README.md",
22 | "LICENSE"
23 | ],
24 | "exports": {
25 | ".": "./lib/index.js"
26 | },
27 | "scripts": {
28 | "clean": "rimraf lib",
29 | "build": "npm run clean && tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
30 | "test": "jest --runInBand",
31 | "lint": "eslint src",
32 | "docker": "docker-compose pull && docker-compose -f docker-compose.yml up",
33 | "dockerTest": "docker-compose pull && docker-compose -f docker-compose-test.yml up"
34 | },
35 | "keywords": [
36 | "mlflow",
37 | "mlops",
38 | "machine learning",
39 | "ai",
40 | "data science",
41 | "javascript",
42 | "typescript"
43 | ],
44 | "author": "",
45 | "license": "MIT",
46 | "devDependencies": {
47 | "@eslint/js": "^9.12.0",
48 | "@types/eslint__js": "^8.42.3",
49 | "@types/jest": "^29.5.14",
50 | "@types/node": "^22.5.4",
51 | "eslint": "^9.12.0",
52 | "jest": "^29.7.0",
53 | "rimraf": "^6.0.1",
54 | "ts-jest": "^29.2.5",
55 | "ts-node": "^10.9.2",
56 | "tsc-alias": "^1.8.10",
57 | "tsx": "^4.19.1",
58 | "typescript": "^5.6.2",
59 | "typescript-eslint": "^8.8.0"
60 | },
61 | "engines": {
62 | "node": ">=22.7.0"
63 | },
64 | "dependencies": {
65 | "@tensorflow/tfjs-node": "^4.22.0",
66 | "dotenv": "^16.4.5"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/mlflow/src/index.ts:
--------------------------------------------------------------------------------
1 | import Mlflow from './mlflow';
2 |
3 | export default Mlflow;
4 |
--------------------------------------------------------------------------------
/mlflow/src/mlflow.ts:
--------------------------------------------------------------------------------
1 | import ExperimentClient from './tracking/ExperimentClient';
2 | import ExperimentManager from './workflows/ExperimentManager';
3 | import RunClient from './tracking/RunClient';
4 | import RunManager from './workflows/RunManager';
5 | import ModelRegistryClient from './model-registry/ModelRegistryClient';
6 | import ModelVersionClient from './model-registry/ModelVersionClient';
7 | import ModelManager from './workflows/ModelManager';
8 |
9 | type ComponentName = keyof Mlflow['components'];
10 |
11 | class Mlflow {
12 | private components: {
13 | experimentClient: ExperimentClient;
14 | experimentManager: ExperimentManager;
15 | runClient: RunClient;
16 | runManager: RunManager;
17 | modelRegistryClient: ModelRegistryClient;
18 | modelVersionClient: ModelVersionClient;
19 | modelManager: ModelManager;
20 | };
21 |
22 | constructor(trackingUri: string) {
23 | this.components = {
24 | experimentClient: new ExperimentClient(trackingUri),
25 | experimentManager: new ExperimentManager(trackingUri),
26 | runClient: new RunClient(trackingUri),
27 | runManager: new RunManager(trackingUri),
28 | modelRegistryClient: new ModelRegistryClient(trackingUri),
29 | modelVersionClient: new ModelVersionClient(trackingUri),
30 | modelManager: new ModelManager(trackingUri),
31 | };
32 |
33 | this.initializeMethods();
34 | }
35 |
36 | private initializeMethods(): void {
37 | (Object.keys(this.components) as ComponentName[]).forEach(
38 | (componentName) => {
39 | const component = this.components[componentName];
40 | Object.getOwnPropertyNames(Object.getPrototypeOf(component))
41 | .filter(
42 | (name) =>
43 | typeof (component as any)[name] === 'function' &&
44 | name !== 'constructor'
45 | )
46 | .forEach((methodName) => {
47 | (this as any)[methodName] = (...args: any[]) =>
48 | (component as any)[methodName](...args);
49 | });
50 | }
51 | );
52 | }
53 |
54 | // Getter methods for direct access to clients and managers
55 | getExperimentClient(): ExperimentClient {
56 | return this.components.experimentClient;
57 | }
58 |
59 | getRunClient(): RunClient {
60 | return this.components.runClient;
61 | }
62 |
63 | getModelRegistryClient(): ModelRegistryClient {
64 | return this.components.modelRegistryClient;
65 | }
66 |
67 | getModelVersionClient(): ModelVersionClient {
68 | return this.components.modelVersionClient;
69 | }
70 |
71 | getExperimentManager(): ExperimentManager {
72 | return this.components.experimentManager;
73 | }
74 |
75 | getRunManager(): RunManager {
76 | return this.components.runManager;
77 | }
78 |
79 | getModelManager(): ModelManager {
80 | return this.components.modelManager;
81 | }
82 | }
83 |
84 | export default Mlflow;
85 |
--------------------------------------------------------------------------------
/mlflow/src/tracking/ExperimentClient.ts:
--------------------------------------------------------------------------------
1 | import { ApiError } from '@utils/apiError';
2 | import { apiRequest } from '@utils/apiRequest';
3 |
4 | class ExperimentClient {
5 | trackingUri: string;
6 | constructor(trackingUri: string) {
7 | this.trackingUri = trackingUri;
8 | }
9 |
10 | /**
11 | * Create an experiment with a name. Returns the ID of the newly created experiment.
12 | * Validates that another experiment with the same name does not already exist and fails if another experiment with the same name already exists.
13 | *
14 | * @param {string} name Experiment name. (required)
15 | * @param {string} artifact_location Optional location where all artifacts for the experiment are stored. If not provided, the remote server will select an appropriate default.
16 | * @param {Array<{key: string, value: string}>} tags Optional collection of tags to set on the experiment.
17 | * @returns {Promise} Returns the ID of the newly created experiment in an object.
18 | * @throws {ApiError} If the API request fails
19 | */
20 | async createExperiment(
21 | name: string,
22 | artifact_location?: string,
23 | tags?: Array<{key: string, value: string}>
24 | ): Promise {
25 |
26 | const { response, data } = await apiRequest(
27 | this.trackingUri,
28 | 'experiments/create',
29 | {
30 | method: 'POST',
31 | body: { name, artifact_location, tags },
32 | }
33 | );
34 |
35 | if (!response.ok) {
36 | throw new ApiError(
37 | `Error creating experiment from tracking server: ${
38 | data.message || response.statusText
39 | }`,
40 | response.status
41 | );
42 | }
43 |
44 | return data.experiment_id;
45 | }
46 |
47 | /**
48 | * Search experiments.
49 | *
50 | * @param {string} filter A filter expression over experiment attributes and tags that allows returning a subset of experiments. The syntax is a subset of SQL. (required)
51 | * @param {number} max_results Maximum number of experiments desired. (required)
52 | * @param {string} page_token Optional token indicating the page of experiments to fetch.
53 | * @param {string[]} order_by Optional list of columns for ordering search results.
54 | * @param {string} view_type Optional qualifier for type of experiments to be returned. See https://mlflow.org/docs/latest/rest-api.html#mlflowviewtype
55 | * @returns {Promise} Returns object containing an array of experiment objects matching the filter,
56 | * and optionally a next_page_token that can be used to retrieve the next page of experiments.
57 | * @throws {ApiError} If the API request fails
58 | */
59 | async searchExperiment(
60 | filter: string,
61 | max_results: number,
62 | page_token?: string,
63 | order_by?: string[],
64 | view_type?: string
65 | ): Promise {
66 |
67 | const { response, data } = await apiRequest(
68 | this.trackingUri,
69 | 'experiments/search',
70 | {
71 | method: 'POST',
72 | body: { filter, max_results, page_token, order_by, view_type },
73 | }
74 | );
75 |
76 | if (!response.ok) {
77 | throw new ApiError(
78 | `Error searching for experiment from tracking server: ${
79 | data.message || response.statusText
80 | }`,
81 | response.status
82 | );
83 | }
84 |
85 | return data;
86 | }
87 |
88 | /**
89 | * Get metadata for an experiment, querying by experiment ID. This method works on deleted experiments.
90 | *
91 | * @param {string} experiment_id ID of the associated experiment. (required)
92 | * @returns {Promise} Returns object containing the matched experiment.
93 | * @throws {ApiError} If the API request fails
94 | */
95 | async getExperiment(
96 | experiment_id: string
97 | ): Promise {
98 |
99 | const { response, data } = await apiRequest(
100 | this.trackingUri,
101 | 'experiments/get',
102 | {
103 | method: 'GET',
104 | params: { experiment_id }
105 | }
106 | );
107 |
108 | if (!response.ok) {
109 | throw new ApiError(
110 | `Error getting experiment from tracking server: ${
111 | data.message || response.statusText
112 | }`,
113 | response.status
114 | );
115 | }
116 |
117 | return data.experiment;
118 | }
119 |
120 | /**
121 | * Get metadata for an experiment, querying by experiment name.
122 | * This endpoint will return deleted experiments,
123 | * but prefers the active experiment if an active and deleted experiment share the same name.
124 | * If multiple deleted experiments share the same name, the API will return one of them.
125 | *
126 | * @param {string} experiment_name ID of the associated experiment. (required)
127 | * @returns {Promise} Returns object containing the matched experiment.
128 | * @throws {ApiError} If the API request fails
129 | */
130 | async getExperimentByName(
131 | experiment_name: string
132 | ): Promise {
133 |
134 | const { response, data } = await apiRequest(
135 | this.trackingUri,
136 | 'experiments/get-by-name',
137 | {
138 | method: 'GET',
139 | params: { experiment_name }
140 | }
141 | );
142 |
143 | if (!response.ok) {
144 | throw new ApiError(
145 | `Error getting experiment by name from tracking server: ${
146 | data.message || response.statusText
147 | }`,
148 | response.status
149 | );
150 | }
151 |
152 | return data.experiment;
153 | }
154 |
155 | /**
156 | * Mark an experiment for deletion.
157 | *
158 | * @param {string} experiment_id ID of the associated experiment. (required)
159 | * @returns {Promise}
160 | * @throws {ApiError} If the API request fails
161 | */
162 | async deleteExperiment(
163 | experiment_id: string
164 | ): Promise {
165 |
166 | const { response, data } = await apiRequest(
167 | this.trackingUri,
168 | 'experiments/delete',
169 | {
170 | method: 'POST',
171 | body: { experiment_id },
172 | }
173 | );
174 |
175 | if (!response.ok) {
176 | throw new ApiError(
177 | `Error deleting experiment from tracking server: ${
178 | data.message || response.statusText
179 | }`,
180 | response.status
181 | );
182 | };
183 | }
184 |
185 | /**
186 | * Restore an experiment marked for deletion.
187 | *
188 | * @param {string} experiment_id ID of the associated experiment. (required)
189 | * @returns {Promise}
190 | * @throws {ApiError} If the API request fails
191 | */
192 | async restoreExperiment(
193 | experiment_id: string
194 | ): Promise {
195 |
196 | const { response, data } = await apiRequest(
197 | this.trackingUri,
198 | 'experiments/restore',
199 | {
200 | method: 'POST',
201 | body: { experiment_id },
202 | }
203 | );
204 |
205 | if (!response.ok) {
206 | throw new ApiError(
207 | `Error restoring experiment from tracking server: ${
208 | data.message || response.statusText
209 | }`,
210 | response.status
211 | );
212 | }
213 | }
214 |
215 | /**
216 | * Update experiment name.
217 | *
218 | * @param {string} experiment_id ID of the associated experiment. (required)
219 | * @param {string} new_name The experiment’s name is changed to the new name. The new name must be unique. (required)
220 | * @returns {Promise}
221 | * @throws {ApiError} If the API request fails
222 | */
223 | async updateExperiment(
224 | experiment_id: string,
225 | new_name: string
226 | ): Promise {
227 |
228 | const { response, data } = await apiRequest(
229 | this.trackingUri,
230 | 'experiments/update',
231 | {
232 | method: 'POST',
233 | body: { experiment_id, new_name },
234 | }
235 | );
236 |
237 | if (!response.ok) {
238 | throw new ApiError(
239 | `Error updating experiment from tracking server: ${
240 | data.message || response.statusText
241 | }`,
242 | response.status
243 | );
244 | }
245 | }
246 |
247 | /**
248 | * Set a tag on an experiment.
249 | *
250 | * @param {string} experiment_id ID of the experiment under which to log the tag. (required)
251 | * @param {string} key Name of the tag. (required)
252 | * @param {string} value String value of the tag being logged. (required)
253 | * @returns {Promise}
254 | * @throws {ApiError} If the API request fails
255 | */
256 | async setExperimentTag(
257 | experiment_id: string,
258 | key: string,
259 | value: string
260 | ): Promise {
261 |
262 | const { response, data } = await apiRequest(
263 | this.trackingUri,
264 | 'experiments/set-experiment-tag',
265 | {
266 | method: 'POST',
267 | body: { experiment_id, key, value },
268 | }
269 | );
270 |
271 | if (!response.ok) {
272 | throw new ApiError(
273 | `Error setting tag from tracking server: ${
274 | data.message || response.statusText
275 | }`,
276 | response.status
277 | );
278 | }
279 | }
280 | }
281 |
282 | export default ExperimentClient;
--------------------------------------------------------------------------------
/mlflow/src/utils/apiError.ts:
--------------------------------------------------------------------------------
1 | export class ApiError extends Error {
2 | statusCode: number;
3 |
4 | constructor(message: string, statusCode: number) {
5 | super(message);
6 | this.name = 'ApiError';
7 | this.statusCode = statusCode;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/mlflow/src/utils/apiRequest.ts:
--------------------------------------------------------------------------------
1 | interface RequestOptions {
2 | method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
3 | body?: Record;
4 | params?: Record;
5 | }
6 |
7 | interface ApiResponse {
8 | response: Response;
9 | data: T;
10 | }
11 |
12 | /**
13 | * Utility function for making API requests to the MLflow server.
14 | *
15 | * @param baseUrl - The base URL of the MLflow server
16 | * @param endpoint - The API endpoint
17 | * @param options - Request options
18 | * @returns A promise that resolves to the response and data
19 | */
20 | export async function apiRequest(
21 | baseUrl: string,
22 | endpoint: string,
23 | options: RequestOptions
24 | ): Promise> {
25 | let url = `${baseUrl}/api/2.0/mlflow/${endpoint}`;
26 | const { method, body, params } = options;
27 |
28 | const fetchOptions: RequestInit = {
29 | method,
30 | headers: {
31 | 'Content-Type': 'application/json',
32 | },
33 | };
34 |
35 | if (body) {
36 | fetchOptions.body = JSON.stringify(body);
37 | }
38 |
39 | if (params) {
40 | const searchParams = new URLSearchParams(params);
41 | url += `?${searchParams.toString()}`;
42 | }
43 |
44 | const response = await fetch(url, fetchOptions);
45 | const data = (await response.json()) as T;
46 |
47 | return { response, data };
48 | }
49 |
50 |
51 |
--------------------------------------------------------------------------------
/mlflow/src/utils/interface.ts:
--------------------------------------------------------------------------------
1 | export interface Run {
2 | info: RunInfo;
3 | data: RunData;
4 | inputs?: RunInputs;
5 | }
6 |
7 | interface RunInfo {
8 | run_id: string;
9 | run_name: string;
10 | experiment_id: string;
11 | status: 'RUNNING' | 'SCHEDULED' | 'FINISHED' | 'FAILED' | 'KILLED';
12 | start_time: number;
13 | end_time: number;
14 | artifact_uri: string;
15 | lifecycle_stage: string;
16 | }
17 |
18 | interface RunData {
19 | metrics: Metrics[];
20 | params: Params[];
21 | tags: Tags[];
22 | }
23 |
24 | interface RunInputs {
25 | dataset_inputs?: DatasetInput[];
26 | }
27 |
28 | interface DatasetInput {
29 | tags?: Tags[];
30 | dataset: {
31 | name: string;
32 | digest: string;
33 | source_type: string;
34 | source: string;
35 | schema?: string;
36 | profile?: string;
37 | };
38 | }
39 |
40 | export interface Metrics {
41 | key: string;
42 | value: number;
43 | timestamp: number;
44 | }
45 |
46 | export interface Params {
47 | key: string;
48 | value: string;
49 | }
50 |
51 | export interface Tags {
52 | key: string;
53 | value: string;
54 | }
55 |
56 | export interface MetricHistoryResponse {
57 | metrics: Metrics[];
58 | next_page_token?: string;
59 | }
60 |
61 | export interface SearchedRuns {
62 | runs: Run[];
63 | next_page_token?: string;
64 | }
65 |
66 | export interface CleanupRuns {
67 | deletedRuns: Run[];
68 | total: number;
69 | dryRun: boolean;
70 | }
71 |
72 | export interface CopyRun {
73 | originalRunId: string;
74 | newRunId: string;
75 | targetExperimentId: string;
76 | }
77 |
78 | export interface Experiment {
79 | experiment_id: string;
80 | name: string;
81 | artifact_location: string;
82 | lifecycle_stage: string;
83 | last_update_time: string;
84 | creation_time: string;
85 | }
--------------------------------------------------------------------------------
/mlflow/src/workflows/RunManager.ts:
--------------------------------------------------------------------------------
1 | import RunClient from '@tracking/RunClient';
2 | import ModelVersionClient from '@model-registry/ModelVersionClient';
3 | import { Run, SearchedRuns } from '@utils/interface';
4 | import { ApiError } from '@utils/apiError';
5 |
6 | class RunManager {
7 | private runClient: RunClient;
8 | private modelVersion: ModelVersionClient;
9 |
10 | constructor(trackingUri: string) {
11 | this.runClient = new RunClient(trackingUri);
12 | this.modelVersion = new ModelVersionClient(trackingUri);
13 | }
14 |
15 | /**
16 | * Delete runs that do not meet certain criteria and return deleted runs.
17 | * Dry run is set to true by default. To delete, set dry run to false.
18 | *
19 | * @param {Array} [experiment_ids] - The IDs of the associated experiments. (required)
20 | * @param {string} query_string - SQL-like query string to filter runs to keep. (required)
21 | * @param {string} metric_key - The metric key for comparison. (required)
22 | * @param {boolean} [dryRun=true] - If true, only simulate the deletion. Defaults to true. (optional)
23 | * @returns {Promise} - An object of deleted runs.
24 | */
25 | async cleanupRuns(
26 | experiment_ids: Array,
27 | query_string: string,
28 | metric_key: string,
29 | dryRun = true
30 | ): Promise {
31 | const deletedRuns = [];
32 | const keepRunIds = new Set();
33 | const runViewType = undefined;
34 | let pageToken = undefined;
35 | const maxResults = 1000;
36 |
37 | try {
38 | do {
39 | // get all runs
40 | const searchResult = (await this.runClient.searchRuns(
41 | experiment_ids,
42 | '',
43 | runViewType,
44 | maxResults,
45 | ['start_time DESC'],
46 | pageToken
47 | )) as SearchedRuns;
48 |
49 | // get runs that match the keep crteria
50 | const keepRunsResult = (await this.runClient.searchRuns(
51 | experiment_ids,
52 | query_string,
53 | runViewType,
54 | maxResults,
55 | ['start_time DESC'],
56 | pageToken
57 | )) as SearchedRuns;
58 |
59 | // Add runs from keepRunsResult to keepResult
60 | keepRunsResult.runs?.forEach((run: Run) =>
61 | keepRunIds.add(run.info.run_id)
62 | );
63 |
64 | // Process each run
65 | for (const run of searchResult.runs) {
66 | const metrics = run.data.metrics;
67 | const hasMetricKey = Array.isArray(metrics)
68 | ? metrics.some((metric) => metric.key === metric_key)
69 | : metric_key in metrics;
70 |
71 | if (!hasMetricKey || keepRunIds.has(run.info.run_id)) {
72 | keepRunIds.add(run.info.run_id);
73 | } else {
74 | deletedRuns.push(run);
75 | if (!dryRun) {
76 | await this.runClient.deleteRun(run.info.run_id);
77 | }
78 | }
79 | }
80 | pageToken = searchResult.next_page_token;
81 | } while (pageToken);
82 |
83 | return {
84 | deletedRuns: deletedRuns,
85 | total: deletedRuns.length,
86 | dryRun,
87 | };
88 | } catch (error) {
89 | if (error instanceof ApiError) {
90 | console.error(`API Error (${error.statusCode}): ${error.message}`);
91 | } else {
92 | console.error('An unexpected error occurred: ', error);
93 | }
94 | throw error;
95 | }
96 | }
97 |
98 | /**
99 | * Copy run from one experiment to another without artifactss and models.
100 | * Artifacts and models detail tagged in new run as reference.
101 | *
102 | * @param {string} run_id - The ID of the run to be copied. (required)
103 | * @param {string} target_experiment_id - The ID of the target experiment. (required)
104 | * @param {string} run_name - The name of the new run in target experiment. (optional)
105 | * @returns {Promise} - An object detail of the copied run.
106 | */
107 | async copyRun(
108 | run_id: string,
109 | target_experiment_id: string,
110 | run_name = null
111 | ): Promise {
112 | try {
113 | // get original run
114 | const originalRun = (await this.runClient.getRun(run_id)) as Run;
115 |
116 | // create a new run in the target experiment
117 | const newRun = (await this.runClient.createRun(
118 | target_experiment_id,
119 | undefined,
120 | originalRun.info.start_time
121 | )) as Run;
122 |
123 | const newRunId = newRun.info.run_id;
124 |
125 | const endTime = originalRun.info.end_time || undefined;
126 |
127 | // copy run information
128 | await this.runClient.updateRun(
129 | newRunId,
130 | originalRun.info.status,
131 | endTime
132 | );
133 |
134 | if (originalRun.info.lifecycle_stage !== 'active') {
135 | await this.runClient.setTag(
136 | newRunId,
137 | 'mlflow.lifecycleStage',
138 | originalRun.info.lifecycle_stage
139 | );
140 | }
141 |
142 | // copy parameters
143 | if (originalRun.data.params) {
144 | for (const param of originalRun.data.params) {
145 | await this.runClient.logParam(newRunId, param.key, param.value);
146 | }
147 | }
148 |
149 | // copy metrics
150 | if (originalRun.data.metrics) {
151 | for (const metric of originalRun.data.metrics) {
152 | await this.runClient.logMetric(newRunId, metric.key, metric.value);
153 | }
154 | }
155 |
156 | // copy tags
157 | if (originalRun.data.tags) {
158 | for (const tag of originalRun.data.tags) {
159 | await this.runClient.setTag(newRunId, tag.key, tag.value);
160 | }
161 | }
162 |
163 | // copy inputs
164 | if (
165 | originalRun.inputs &&
166 | originalRun.inputs.dataset_inputs &&
167 | originalRun.inputs.dataset_inputs.length > 0
168 | ) {
169 | // Log each dataset input separately
170 | for (const datasetInput of originalRun.inputs.dataset_inputs) {
171 | await this.runClient.logInputs(newRunId, [datasetInput]);
172 | }
173 | }
174 |
175 | // update the new run name
176 | if (run_name) {
177 | await this.runClient.setTag(newRunId, 'mlflow.runName', run_name);
178 | }
179 |
180 | // handle models (reference only)
181 | const modelVersions = await this.modelVersion.searchModelVersions(
182 | `run_id = '${run_id}'`
183 | );
184 | if (modelVersions && modelVersions.length > 0) {
185 | for (const model of modelVersions) {
186 | if (
187 | typeof model === 'object' &&
188 | model !== null &&
189 | 'name' in model &&
190 | 'version' in model &&
191 | 'current_stage' in model &&
192 | 'source' in model
193 | ) {
194 | await this.runClient.setTag(
195 | newRunId,
196 | `original_model_${model.name}`,
197 | JSON.stringify({
198 | name: model.name,
199 | version: model.version,
200 | current_stage: model.current_stage,
201 | source: model.source,
202 | })
203 | );
204 | }
205 | }
206 | await this.runClient.setTag(
207 | newRunId,
208 | 'mlflow.note.models',
209 | 'Models not copied, see original run.'
210 | );
211 | }
212 |
213 | // set description for the new run
214 | const description =
215 | `This run was copied from experiment ${originalRun.info.experiment_id}, original run ID: ${run_id}. ` +
216 | `Original artifact URI: ${originalRun.info.artifact_uri}.`;
217 |
218 | await this.runClient.setTag(newRunId, 'mlflow.note.content', description);
219 |
220 | // set additional tags for the new run
221 | await this.runClient.setTag(newRunId, 'mlflow.source.run_id', run_id);
222 |
223 | await this.runClient.setTag(
224 | newRunId,
225 | 'mlflow.source.experiment_id',
226 | originalRun.info.experiment_id
227 | );
228 |
229 | await this.runClient.setTag(
230 | newRunId,
231 | 'mlflow.note.artifacts',
232 | 'Artifacts not copied - reference original run'
233 | );
234 |
235 | // return copy run details
236 | return {
237 | originalRunId: run_id,
238 | newRunId: newRunId,
239 | targetExperimentId: target_experiment_id,
240 | };
241 | } catch (error) {
242 | if (error instanceof ApiError) {
243 | console.error(`API Error (${error.statusCode}): ${error.message}`);
244 | } else {
245 | console.error('An unexpected error occurred: ', error);
246 | }
247 | throw error;
248 | }
249 | }
250 | }
251 |
252 | export default RunManager;
253 |
--------------------------------------------------------------------------------
/mlflow/tests/ExperimentClient.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
2 | import ExperimentClient from '../src/tracking/ExperimentClient';
3 | import { ApiError } from '../src/utils/apiError';
4 | import {
5 | createTestExperiment,
6 | deleteTestExperiments,
7 | experimentProperties,
8 | ExpSearchResults,
9 | TRACKING_SERVER_URI,
10 | } from './testUtils';
11 |
12 | describe('ExperimentClient', () => {
13 | let experimentClient: ExperimentClient;
14 | const testIds: string[] = [];
15 |
16 | beforeAll(async () => {
17 | // Add a small delay to ensure MLflow is fully ready
18 | await new Promise((resolve) => setTimeout(resolve, 2000));
19 | experimentClient = new ExperimentClient(TRACKING_SERVER_URI);
20 | });
21 |
22 | describe('createExperiment', () => {
23 | test('should create an experiment and return the experiment ID', async () => {
24 | const testExperimentId: string = await createTestExperiment();
25 | testIds.push(testExperimentId);
26 | expect(typeof testExperimentId).toBe('string');
27 | expect(testExperimentId).toBeTruthy();
28 | });
29 |
30 | test('should throw error if name is missing', async () => {
31 | // @ts-expect-error: testing for missing arguments
32 | await expect(experimentClient.createExperiment()).rejects.toThrow(
33 | ApiError
34 | );
35 | // @ts-expect-error: testing for missing arguments
36 | await expect(experimentClient.createExperiment()).rejects.toThrow(
37 | /Error creating experiment from tracking server:/
38 | );
39 | });
40 |
41 | test('should throw error if name is already in use', async () => {
42 | const experimentName: string = `Test experiment ${Date.now()}`;
43 | testIds.push(await experimentClient.createExperiment(experimentName));
44 | await expect(
45 | experimentClient.createExperiment(experimentName)
46 | ).rejects.toThrow(ApiError);
47 | });
48 | });
49 |
50 | describe('searchExperiment', () => {
51 | beforeAll(async () => {
52 | for (let i = 0; i < 5; i++) {
53 | const search: string = await experimentClient.createExperiment(
54 | `Search test ${Date.now()}`
55 | );
56 | testIds.push(search);
57 | }
58 | });
59 |
60 | test('should return valid search results', async () => {
61 | const results: ExpSearchResults = await experimentClient.searchExperiment(
62 | "name LIKE 'Search test%'",
63 | 4
64 | );
65 |
66 | expect(results.experiments).toBeDefined();
67 | expect(results.next_page_token).toBeDefined();
68 | expect(results.experiments).toHaveLength(4);
69 | results.experiments?.forEach((result) => {
70 | for (const property of experimentProperties) {
71 | expect(result).toHaveProperty(property);
72 | }
73 | });
74 | expect(typeof results.next_page_token).toBe('string');
75 | });
76 | });
77 |
78 | describe('getExperiment', () => {
79 | test('should return experiment information', async () => {
80 | const expId: string = await createTestExperiment();
81 | const experiment = await experimentClient.getExperiment(expId);
82 | testIds.push(expId);
83 | for (const property of experimentProperties) {
84 | expect(experiment).toHaveProperty(property);
85 | }
86 | });
87 |
88 | test('should throw error if experiment ID is missing', async () => {
89 | // @ts-expect-error: testing for missing arguments
90 | await expect(experimentClient.getExperiment()).rejects.toThrow(ApiError);
91 | });
92 | });
93 |
94 | describe('getExperimentByName', () => {
95 | test('should return experiment information', async () => {
96 | const name: string = `Test experiment ${Date.now()}`;
97 | testIds.push(await experimentClient.createExperiment(name));
98 | const experiment = await experimentClient.getExperimentByName(name);
99 | for (const property of experimentProperties) {
100 | expect(experiment).toHaveProperty(property);
101 | }
102 | });
103 |
104 | test('should throw error if experiment name is missing', async () => {
105 | // @ts-expect-error: testing for missing arguments
106 | await expect(experimentClient.getExperimentByName()).rejects.toThrow(
107 | ApiError
108 | );
109 | });
110 | });
111 |
112 | describe('deleteExperiment', () => {
113 | test('should delete an experiment', async () => {
114 | const name: string = `Test experiment ${Date.now()}`;
115 | const idToDelete: string = await experimentClient.createExperiment(name);
116 | await experimentClient.deleteExperiment(idToDelete);
117 | const results: ExpSearchResults = await experimentClient.searchExperiment(
118 | `name LIKE '${name}'`,
119 | 4
120 | );
121 | expect(results).toEqual({});
122 | });
123 |
124 | test('should throw error if invalid experiment ID is passed in', async () => {
125 | await expect(
126 | experimentClient.deleteExperiment('invalidExperimentId')
127 | ).rejects.toThrow(ApiError);
128 | });
129 | });
130 |
131 | describe('restoreExperiment', () => {
132 | test('should restore a deleted experiment', async () => {
133 | const name: string = `Test experiment ${Date.now()}`;
134 | const idToDelete: string = await experimentClient.createExperiment(name);
135 | testIds.push(idToDelete);
136 | await experimentClient.deleteExperiment(idToDelete);
137 | await experimentClient.restoreExperiment(idToDelete);
138 | const results: ExpSearchResults = await experimentClient.searchExperiment(
139 | `name LIKE '${name}'`,
140 | 4
141 | );
142 | expect(results.experiments).toBeDefined();
143 | expect(results.experiments).toHaveLength(1);
144 | });
145 |
146 | test('should throw error if invalid experiment ID is passed in', async () => {
147 | await expect(
148 | experimentClient.restoreExperiment('invalidExperimentId')
149 | ).rejects.toThrow(ApiError);
150 | });
151 | });
152 |
153 | describe('updateExperiment', () => {
154 | test("should update an experiment's name", async () => {
155 | const name: string = `Test experiment ${Date.now()}`;
156 | const exp: string = await experimentClient.createExperiment(name);
157 | testIds.push(exp);
158 | const updatedName: string = `${name}_UPDATE`;
159 | await experimentClient.updateExperiment(exp, updatedName);
160 | const results: ExpSearchResults = await experimentClient.searchExperiment(
161 | `name LIKE '${updatedName}'`,
162 | 4
163 | );
164 | expect(results.experiments).toBeDefined();
165 | expect(results.experiments).toHaveLength(1);
166 | expect(results.experiments?.[0].experiment_id).toBe(exp);
167 | });
168 |
169 | test('should throw error if invalid experiment ID is passed in', async () => {
170 | await expect(
171 | experimentClient.updateExperiment(
172 | 'invalidExperimentId',
173 | 'invalidExperimentIdUpdate'
174 | )
175 | ).rejects.toThrow(ApiError);
176 | });
177 | });
178 |
179 | describe('setExperimentTag', () => {
180 | test('should set a tag on an experiment', async () => {
181 | const date: number = Date.now();
182 | const name: string = `Test experiment ${date}`;
183 | const exp: string = await experimentClient.createExperiment(name);
184 | testIds.push(exp);
185 | await experimentClient.setExperimentTag(exp, 'tag1', `value${date}`);
186 | const results: ExpSearchResults = await experimentClient.searchExperiment(
187 | `tags.tag1 = "value${date}"`,
188 | 4
189 | );
190 | expect(results.experiments).toBeDefined();
191 | expect(results.experiments).toHaveLength(1);
192 | expect(results.experiments?.[0].experiment_id).toBe(exp);
193 | });
194 |
195 | test('should throw error if invalid experiment ID is passed in', async () => {
196 | await expect(
197 | experimentClient.setExperimentTag(
198 | 'invalidExperimentId',
199 | 'tag1',
200 | 'value1'
201 | )
202 | ).rejects.toThrow(ApiError);
203 | });
204 | });
205 |
206 | afterAll(async () => await deleteTestExperiments(testIds));
207 | });
208 |
--------------------------------------------------------------------------------
/mlflow/tests/ExperimentManager.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, beforeAll, afterAll } from '@jest/globals';
2 | import { ApiError } from '../src/utils/apiError';
3 | import ExperimentClient from '../src/tracking/ExperimentClient';
4 | import ExperimentManager from '../src/workflows/ExperimentManager';
5 | import {
6 | createTestExperiment,
7 | deleteTestExperiments,
8 | runProperties,
9 | TRACKING_SERVER_URI,
10 | } from './testUtils';
11 |
12 | describe('ExperimentManager', () => {
13 | let experimentClient: ExperimentClient;
14 | let experimentManager: ExperimentManager;
15 | const testIds: string[] = [];
16 |
17 | const metrics = [
18 | { key: 'metric1', value: 0.111, timestamp: Date.now() },
19 | { key: 'metric2', value: 0.222, timestamp: Date.now() },
20 | ];
21 | const params = [
22 | { key: 'testParam', value: 'testParamValue' },
23 | { key: 'testParam2', value: 'testParamValue2' },
24 | ];
25 | const tags = [
26 | { key: 'testKey', value: 'testValue' },
27 | { key: 'testKey2', value: 'testValue2' },
28 | ];
29 | const model = {
30 | artifact_path: 'model',
31 | flavors: {
32 | python_function: {
33 | model_path: 'model.pkl',
34 | loader_module: 'mlflow.sklearn',
35 | python_version: '3.8.10',
36 | },
37 | },
38 | model_url: 'STRING',
39 | model_uuid: 'STRING',
40 | utc_time_created: Date.now(),
41 | mlflow_version: 'STRING',
42 | };
43 | const metricsAll = [
44 | [{ key: 'metric1', value: 0.1, timestamp: Date.now() }],
45 | [{ key: 'metric1', value: 0.2, timestamp: Date.now() }],
46 | [{ key: 'metric1', value: 0.3, timestamp: Date.now() }],
47 | [{ key: 'metric1', value: 0.4, timestamp: Date.now() }],
48 | [{ key: 'metric1', value: 0.5, timestamp: Date.now() }],
49 | ];
50 |
51 | beforeAll(async () => {
52 | // Add a small delay to ensure MLflow is fully ready
53 | await new Promise((resolve) => setTimeout(resolve, 2000));
54 | experimentClient = new ExperimentClient(TRACKING_SERVER_URI);
55 | experimentManager = new ExperimentManager(TRACKING_SERVER_URI);
56 | });
57 |
58 | describe('runExistingExperiment', () => {
59 | test('should run an existing experiment and return the run object', async () => {
60 | const exp: string = await createTestExperiment();
61 | testIds.push(exp);
62 | const run = await experimentManager.runExistingExperiment(
63 | exp,
64 | undefined,
65 | metrics,
66 | params,
67 | tags,
68 | model
69 | );
70 | for (const property of runProperties) {
71 | expect(run).toHaveProperty(property);
72 | }
73 | });
74 |
75 | test('should throw error if an invalid experiment ID is passed in', async () => {
76 | const exp: string = await createTestExperiment();
77 | testIds.push(exp);
78 | await expect(
79 | experimentManager.runExistingExperiment(
80 | 'invalidExperimentId',
81 | undefined,
82 | metrics,
83 | params,
84 | tags,
85 | model
86 | )
87 | ).rejects.toThrow(ApiError);
88 | });
89 | });
90 |
91 | describe('runNewExperiment', () => {
92 | test('should run a new experiment and return the run object', async () => {
93 | const name: string = `Test experiment ${Date.now()}`;
94 | const run: {
95 | experiment_id?: string;
96 | } = await experimentManager.runNewExperiment(
97 | name,
98 | undefined,
99 | metrics,
100 | params,
101 | tags,
102 | model
103 | );
104 | if (run.experiment_id) {
105 | testIds.push(run.experiment_id);
106 | }
107 | for (const property of runProperties) {
108 | expect(run).toHaveProperty(property);
109 | }
110 | });
111 |
112 | test('should throw error if an invalid experiment name is passed in', async () => {
113 | const name: string = `Test experiment ${Date.now()}`;
114 | const exp: string = await experimentClient.createExperiment(name);
115 | testIds.push(exp);
116 | await expect(
117 | experimentManager.runNewExperiment(
118 | name,
119 | undefined,
120 | metrics,
121 | params,
122 | tags,
123 | model
124 | )
125 | ).rejects.toThrow(ApiError);
126 | });
127 | });
128 |
129 | describe('experimentSummary', () => {
130 | test("should return an array of all the passed-in experiment's runs, sorted according to the passed-in metric", async () => {
131 | const exp: string = await createTestExperiment();
132 | testIds.push(exp);
133 | for (const metric of metricsAll) {
134 | await experimentManager.runExistingExperiment(
135 | exp,
136 | undefined,
137 | metric,
138 | params,
139 | tags,
140 | model
141 | );
142 | }
143 |
144 | type ExperimentSummaryResult = {
145 | metric1?: number;
146 | };
147 |
148 | const summary: ExperimentSummaryResult[] =
149 | await experimentManager.experimentSummary(exp, 'metric1', 'DESC');
150 |
151 | expect(Array.isArray(summary)).toBe(true);
152 | expect(summary.length).toBe(5);
153 | expect(summary[0].metric1).toBe(0.5);
154 | expect(summary[1].metric1).toBe(0.4);
155 | expect(summary[2].metric1).toBe(0.3);
156 | expect(summary[3].metric1).toBe(0.2);
157 | expect(summary[4].metric1).toBe(0.1);
158 | });
159 | });
160 |
161 | afterAll(async () => await deleteTestExperiments(testIds));
162 | });
163 |
--------------------------------------------------------------------------------
/mlflow/tests/ModelRegistryClient.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, beforeAll, beforeEach } from '@jest/globals';
2 | // @ts-ignore
3 | import ModelRegistryClient from '@model-registry/ModelRegistryClient';
4 | // @ts-ignore
5 | import ModelVersionClient from '@model-registry/ModelVersionClient';
6 | // @ts-ignore
7 | import RunClient from '@tracking/RunClient';
8 |
9 | interface keyable {
10 | [key: string]: any;
11 | }
12 |
13 | describe('ModelRegistryClient Integration Tests', () => {
14 | let modelRegistryClient: ModelRegistryClient;
15 | let modelVersionClient: ModelVersionClient;
16 | let runClient: RunClient;
17 | let modelName: string;
18 | let runId: string;
19 | let artifactUri: string;
20 |
21 | beforeAll(async () => {
22 | await new Promise((resolve) => setTimeout(resolve, 2000));
23 | modelRegistryClient = new ModelRegistryClient('http://localhost:5002');
24 | modelVersionClient = new ModelVersionClient('http://localhost:5002');
25 | runClient = new RunClient('http://localhost:5002');
26 |
27 | const run = (await runClient.createRun('0')) as keyable;
28 | runId = run.info.run_id;
29 | artifactUri = `${run.info.artifact_uri}/model`;
30 | });
31 |
32 | beforeEach(() => {
33 | modelName = `test_model_${Date.now()}`;
34 | });
35 |
36 | describe('createRegisteredModel', () => {
37 | test('should create a model with required name only', async () => {
38 | const response = (await modelRegistryClient.createRegisteredModel(
39 | modelName
40 | )) as keyable;
41 |
42 | expect(response.name).toBe(modelName);
43 | });
44 |
45 | test('should throw error for duplicate model name', async () => {
46 | await modelRegistryClient.createRegisteredModel(modelName);
47 |
48 | await expect(
49 | modelRegistryClient.createRegisteredModel(modelName)
50 | ).rejects.toThrow('already exists');
51 | });
52 | });
53 |
54 | describe('getRegisteredModel', () => {
55 | test('should get existing model', async () => {
56 | await modelRegistryClient.createRegisteredModel(modelName);
57 |
58 | const response = (await modelRegistryClient.getRegisteredModel(
59 | modelName
60 | )) as keyable;
61 |
62 | expect(response.name).toBe(modelName);
63 | });
64 |
65 | test('should throw error for non-existent model', async () => {
66 | await expect(
67 | modelRegistryClient.getRegisteredModel('non_existent_model')
68 | ).rejects.toThrow('not found');
69 | });
70 | });
71 |
72 | describe('updateRegisteredModel', () => {
73 | test('should update model description', async () => {
74 | await modelRegistryClient.createRegisteredModel(modelName);
75 | const newDescription = 'Updated description';
76 |
77 | const response = (await modelRegistryClient.updateRegisteredModel(
78 | modelName,
79 | newDescription
80 | )) as keyable;
81 |
82 | expect(response.description).toBe(newDescription);
83 | });
84 |
85 | test('should throw error for non-existent model', async () => {
86 | await expect(
87 | modelRegistryClient.updateRegisteredModel(
88 | 'non_existent_model',
89 | 'description'
90 | )
91 | ).rejects.toThrow('not found');
92 | });
93 | });
94 |
95 | describe('renameRegisteredModel', () => {
96 | test('should rename model successfully', async () => {
97 | await modelRegistryClient.createRegisteredModel(modelName);
98 | const newName = `${modelName}_renamed`;
99 |
100 | const response = (await modelRegistryClient.renameRegisteredModel(
101 | modelName,
102 | newName
103 | )) as keyable;
104 |
105 | expect(response.name).toBe(newName);
106 | });
107 |
108 | test('should throw error when renaming to existing name', async () => {
109 | const existingName = `${modelName}_existing`;
110 | await modelRegistryClient.createRegisteredModel(modelName);
111 | await modelRegistryClient.createRegisteredModel(existingName);
112 |
113 | await expect(
114 | modelRegistryClient.renameRegisteredModel(modelName, existingName)
115 | ).rejects.toThrow('already exists');
116 | });
117 | });
118 |
119 | describe('getLatestModelVersions', () => {
120 | test('should get latest versions of model', async () => {
121 | await modelRegistryClient.createRegisteredModel(modelName);
122 | await modelVersionClient.createModelVersion(
123 | modelName,
124 | artifactUri,
125 | runId
126 | );
127 |
128 | const response = await modelRegistryClient.getLatestModelVersions(
129 | modelName
130 | );
131 | expect(response).toBeDefined();
132 | });
133 | });
134 |
135 | describe('searchRegisteredModels', () => {
136 | test('should search models with max_results', async () => {
137 | await modelRegistryClient.createRegisteredModel(modelName);
138 |
139 | const response = (await modelRegistryClient.searchRegisteredModels(
140 | `name LIKE '${modelName}%'`,
141 | 1
142 | )) as keyable;
143 |
144 | expect(response.registered_models).toBeDefined();
145 | });
146 |
147 | test('should search with order_by', async () => {
148 | await modelRegistryClient.createRegisteredModel(modelName);
149 |
150 | const response = (await modelRegistryClient.searchRegisteredModels(
151 | `name LIKE '${modelName}%'`,
152 | 1,
153 | ['name ASC']
154 | )) as keyable;
155 |
156 | expect(response.registered_models).toBeDefined();
157 | });
158 | });
159 |
160 | describe('model tags', () => {
161 | test('should set and delete tag', async () => {
162 | await modelRegistryClient.createRegisteredModel(modelName);
163 | const tagKey = 'test_tag';
164 | const tagValue = 'test_value';
165 |
166 | await modelRegistryClient.setRegisteredModelTag(
167 | modelName,
168 | tagKey,
169 | tagValue
170 | );
171 |
172 | const model = (await modelRegistryClient.getRegisteredModel(
173 | modelName
174 | )) as keyable;
175 |
176 | expect(model.tags?.[0]?.key).toBe(tagKey);
177 | expect(model.tags?.[0]?.value).toBe(tagValue);
178 |
179 | await modelRegistryClient.deleteRegisteredModelTag(modelName, tagKey);
180 |
181 | const updatedModel = (await modelRegistryClient.getRegisteredModel(
182 | modelName
183 | )) as keyable;
184 | expect(updatedModel.tags?.length || 0).toBe(0);
185 | });
186 | });
187 |
188 | describe('model aliases', () => {
189 | test('should set, get, and delete alias', async () => {
190 | await modelRegistryClient.createRegisteredModel(modelName);
191 | const version = (await modelVersionClient.createModelVersion(
192 | modelName,
193 | artifactUri,
194 | runId
195 | )) as keyable;
196 |
197 | const alias = 'production';
198 | await modelRegistryClient.setRegisteredModelAlias(
199 | modelName,
200 | alias,
201 | version.version
202 | );
203 |
204 | const modelVersion = (await modelRegistryClient.getModelVersionByAlias(
205 | modelName,
206 | alias
207 | )) as keyable;
208 | expect(modelVersion.version).toBe(version.version);
209 |
210 | await modelRegistryClient.deleteRegisteredModelAlias(modelName, alias);
211 |
212 | await expect(
213 | modelRegistryClient.getModelVersionByAlias(modelName, alias)
214 | ).rejects.toThrow();
215 | });
216 |
217 | test('should throw error for non-existent model alias', async () => {
218 | await modelRegistryClient.createRegisteredModel(modelName);
219 | await expect(
220 | modelRegistryClient.getModelVersionByAlias(
221 | modelName,
222 | 'non_existent_alias'
223 | )
224 | ).rejects.toThrow();
225 | });
226 | });
227 |
228 | describe('deleteRegisteredModel', () => {
229 | test('should delete model', async () => {
230 | await modelRegistryClient.createRegisteredModel(modelName);
231 | await modelRegistryClient.deleteRegisteredModel(modelName);
232 |
233 | await expect(
234 | modelRegistryClient.getRegisteredModel(modelName)
235 | ).rejects.toThrow('not found');
236 | });
237 |
238 | test('should throw error for non-existent model', async () => {
239 | await expect(
240 | modelRegistryClient.deleteRegisteredModel('non_existent_model')
241 | ).rejects.toThrow('not found');
242 | });
243 | });
244 | });
245 |
--------------------------------------------------------------------------------
/mlflow/tests/RunManager.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, beforeEach, afterAll } from '@jest/globals';
2 | import RunManager from '../src/workflows/RunManager';
3 | import RunClient from '../src/tracking/RunClient';
4 | import ExperimentClient from '../src/tracking/ExperimentClient';
5 | import { Run, CleanupRuns, CopyRun } from '../src/utils/interface';
6 | import { TRACKING_SERVER_URI, TEST_DATA } from './testUtils';
7 |
8 | describe('RunManager', () => {
9 | let runManager: RunManager;
10 | let runClient: RunClient;
11 | let experimentClient: ExperimentClient;
12 | let experimentId: string;
13 | const runIds: string[] = [];
14 | const experimentsToDelete: string[] = [];
15 |
16 | beforeEach(async () => {
17 | await new Promise((resolve) => setTimeout(resolve, 2000));
18 | runClient = new RunClient(TRACKING_SERVER_URI);
19 | experimentClient = new ExperimentClient(TRACKING_SERVER_URI);
20 | runManager = new RunManager(TRACKING_SERVER_URI);
21 | });
22 |
23 | afterAll(async () => {
24 | for (const runId of runIds) {
25 | await runClient.deleteRun(runId);
26 | }
27 |
28 | for (const expId of experimentsToDelete) {
29 | await experimentClient.deleteExperiment(expId);
30 | }
31 | });
32 |
33 | describe('cleanupRuns', () => {
34 | beforeEach(async () => {
35 | const timestamp = Date.now();
36 | experimentId = await experimentClient.createExperiment(
37 | `Testing ${timestamp}`
38 | );
39 | experimentsToDelete.push(experimentId);
40 |
41 | // create test runs
42 | const createRun = async (metricKey: string, metricValue: number) => {
43 | const run = (await runClient.createRun(experimentId)) as Run;
44 | await runClient.logMetric(run.info.run_id, metricKey, metricValue);
45 | runIds.push(run.info.run_id);
46 | return run;
47 | };
48 |
49 | await createRun('metric1', 10);
50 | await createRun('metric1', 20);
51 | await createRun('metric2', 30);
52 | await createRun('metric3', 40);
53 | });
54 |
55 | test('- Should delete runs not matching criteria', async () => {
56 | (await runClient.searchRuns([experimentId])) as { runs: Run[] };
57 |
58 | const result = (await runManager.cleanupRuns(
59 | [experimentId],
60 | 'metrics.metric1 > 15',
61 | 'metric1',
62 | false // not a dry run
63 | )) as CleanupRuns;
64 |
65 | const remainingRuns = (await runClient.searchRuns([experimentId])) as {
66 | runs: Run[];
67 | };
68 |
69 | expect(result.dryRun).toBe(false);
70 | expect(result.total).toBe(1);
71 | expect(result.deletedRuns.length).toBe(1);
72 | expect(remainingRuns.runs.length).toBe(3);
73 |
74 | // verify that remaining runs all have metric1 > 15
75 | for (const run of remainingRuns.runs) {
76 | const metric1 = run.data.metrics.find((m) => m.key === 'metric1');
77 | if (metric1) {
78 | expect(metric1.value).toBeGreaterThan(15);
79 | }
80 | }
81 | });
82 |
83 | test('- Should not delete runs in dry run mode', async () => {
84 | const initialRuns = (await runClient.searchRuns([experimentId])) as {
85 | runs: Run[];
86 | };
87 |
88 | expect(initialRuns.runs.length).toBe(4);
89 |
90 | const result = (await runManager.cleanupRuns(
91 | [experimentId],
92 | 'metrics.metric1 > 25',
93 | 'metric1',
94 | true // dry run
95 | )) as CleanupRuns;
96 |
97 | const remainingRuns = (await runClient.searchRuns([experimentId])) as {
98 | runs: Run[];
99 | };
100 |
101 | expect(result.deletedRuns.length).toBe(2);
102 | expect(result.total).toBe(2);
103 | expect(result.dryRun).toBe(true);
104 | expect(remainingRuns.runs.length).toBe(4);
105 |
106 | // verify the runs identified for deletion
107 | const deletedMetric1Values = result.deletedRuns.map(
108 | (run) => run.data.metrics.find((m) => m.key === 'metric1')?.value
109 | );
110 | expect(deletedMetric1Values).toEqual(expect.arrayContaining([10, 20]));
111 |
112 | // verify that runs with metric2 and metric3 are not in deletedRuns
113 | const deletedMetricKeys = result.deletedRuns.flatMap((run) =>
114 | run.data.metrics.map((m) => m.key)
115 | );
116 | expect(deletedMetricKeys).not.toContain('metric2');
117 | expect(deletedMetricKeys).not.toContain('metric3');
118 | });
119 | });
120 |
121 | describe('copyRun', () => {
122 | let originalRunId: string;
123 | let sourceExperimentId: string;
124 | let targetExperimentId: string;
125 | const datasets = [
126 | {
127 | tags: [
128 | { key: 'version', value: '1.0' },
129 | { key: 'environment', value: 'production' },
130 | ],
131 | dataset: {
132 | name: 'test_dataset',
133 | digest: 'abc123',
134 | source_type: 'local',
135 | source: '/path/to/data.csv',
136 | },
137 | },
138 | ];
139 | let model;
140 |
141 | beforeEach(async () => {
142 | const timestamp = Date.now();
143 | sourceExperimentId = await experimentClient.createExperiment(
144 | `Source Exp ${timestamp}`
145 | );
146 | targetExperimentId = await experimentClient.createExperiment(
147 | `Target Exp ${timestamp}`
148 | );
149 | experimentsToDelete.push(sourceExperimentId, targetExperimentId);
150 |
151 | // log data for original run
152 | const run = (await runClient.createRun(sourceExperimentId)) as Run;
153 | originalRunId = run.info.run_id;
154 |
155 | model = {
156 | artifact_path: 'pytorch_dnn',
157 | flavors: {
158 | python_function: {
159 | env: 'conda.yaml',
160 | loader_module: 'mlflow.pytorch',
161 | model_path: 'model.pth',
162 | python_version: '3.8.10',
163 | },
164 | },
165 | mlflow_version: '1.20.2',
166 | model_uuid: '123e4567-e89b-12d3-a456-426614174001',
167 | utc_time_created: '2023-09-14 10:15:00.000000',
168 | run_id: originalRunId,
169 | };
170 |
171 | const model_json = JSON.stringify(model);
172 |
173 | const { metrics, params, tags } = TEST_DATA;
174 |
175 | await runClient.logBatch(originalRunId, metrics, params, tags);
176 |
177 | await runClient.logInputs(originalRunId, datasets);
178 | await runClient.logModel(originalRunId, model_json);
179 | await runClient.updateRun(
180 | originalRunId,
181 | 'FINISHED',
182 | 1694000800000,
183 | 'NewName'
184 | );
185 | });
186 |
187 | test('- Should copy run from one experiment to another', async () => {
188 | const { metrics } = TEST_DATA;
189 |
190 | const result = (await runManager.copyRun(
191 | originalRunId,
192 | targetExperimentId
193 | )) as CopyRun;
194 |
195 | expect(result).toHaveProperty('originalRunId', originalRunId);
196 | expect(result).toHaveProperty('newRunId');
197 | expect(result).toHaveProperty('targetExperimentId', targetExperimentId);
198 |
199 | // fetch copied run and check the metrics
200 | const copiedRun = (await runClient.getRun(result.newRunId)) as Run;
201 |
202 | const metricMatchers = metrics.map((metric) =>
203 | expect.objectContaining({
204 | key: metric.key,
205 | value: metric.value,
206 | })
207 | );
208 |
209 | expect(copiedRun.data.metrics).toEqual(
210 | expect.arrayContaining(metricMatchers)
211 | );
212 | });
213 | });
214 | });
215 |
--------------------------------------------------------------------------------
/mlflow/tests/testUtils.ts:
--------------------------------------------------------------------------------
1 | import ExperimentClient from '../src/tracking/ExperimentClient';
2 | import { Experiment, Metrics, Params, Tags } from '../src/utils/interface';
3 |
4 | export const TRACKING_SERVER_URI: string = 'http://127.0.0.1:5002';
5 |
6 | export const experimentProperties: string[] = [
7 | 'experiment_id',
8 | 'name',
9 | 'artifact_location',
10 | 'lifecycle_stage',
11 | 'last_update_time',
12 | 'creation_time',
13 | ];
14 |
15 | export const runProperties: string[] = [
16 | 'run_id',
17 | 'run_uuid',
18 | 'run_name',
19 | 'experiment_id',
20 | 'user_id',
21 | 'status',
22 | 'start_time',
23 | 'artifact_uri',
24 | 'lifecycle_stage',
25 | ];
26 |
27 | export type ExpSearchResults = {
28 | experiments?: Experiment[];
29 | next_page_token?: string;
30 | };
31 |
32 | const experimentClient = new ExperimentClient(TRACKING_SERVER_URI);
33 |
34 | export const TEST_DATA = {
35 | metrics: [
36 | { key: 'accuracy', value: 0.83, timestamp: 1694000700000 },
37 | { key: 'loss', value: 0.18, timestamp: 1694000700000 },
38 | ] as Metrics[],
39 | params: [
40 | { key: 'learning_rate', value: '0.0001' },
41 | { key: 'batch_size', value: '256' },
42 | ] as Params[],
43 | tags: [
44 | { key: 'model_type', value: 'GradientBoosting' },
45 | { key: 'data_version', value: 'v1.7' },
46 | ] as Tags[],
47 | validModel: {
48 | artifact_path: 'pytorch_dnn',
49 | flavors: {
50 | python_function: {
51 | env: 'conda.yaml',
52 | loader_module: 'mlflow.pytorch',
53 | model_path: 'model.pth',
54 | python_version: '3.8.10',
55 | },
56 | pytorch: {
57 | model_data: 'model.pth',
58 | pytorch_version: '1.9.0',
59 | code: 'model-code',
60 | },
61 | },
62 | utc_time_created: '2023-09-14 10:15:00.000000',
63 | },
64 | };
65 |
66 | export const createTestExperiment = async (
67 | prefix = 'Test experiment'
68 | ): Promise => {
69 | const timestamp = Date.now();
70 | return await experimentClient.createExperiment(`${prefix} ${timestamp}`);
71 | };
72 |
73 | export const deleteTestExperiments = async (experimentIds: string[]) => {
74 | for (const id of experimentIds) {
75 | try {
76 | await experimentClient.deleteExperiment(id);
77 | } catch (err) {
78 | console.warn(`Failed to delete experiment ${id}: ${err}`);
79 | }
80 | }
81 | };
82 |
--------------------------------------------------------------------------------
/mlflow/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | // Basic Options
4 | "target": "ES2018",
5 | "module": "ESNext",
6 | "rootDir": "./src",
7 | "outDir": "./lib",
8 |
9 | // Module Resolution Options
10 | "moduleResolution": "node",
11 | "baseUrl": "./",
12 | "paths": {
13 | "@src/*": ["src/*"],
14 | "@model-registry/*": ["src/model-registry/*"],
15 | "@tracking/*": ["src/tracking/*"],
16 | "@utils/*": ["src/utils/*"],
17 | "@workflows/*": ["src/workflows/*"]
18 | },
19 | "esModuleInterop": true,
20 | "strict": true,
21 | "declaration": true,
22 | "sourceMap": true
23 | },
24 | "include": ["src/**/*"],
25 | "exclude": ["node_modules"],
26 | "tsc-alias": {
27 | "resolveFullPaths": true,
28 | "outDir": "./lib",
29 | "extensionReplacement": [{ "from": ".ts", "to": ".js" }]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/mlflow/tsconfig.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["src/**/*", "tests/**/*"],
4 | "compilerOptions": {
5 | "types": ["jest"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------