Skip to content

Commit fe965be

Browse files
Update API developer docs (#325)
* Add codegen workflow diagram * Describe codegen workflow * Describe API server package modules Closes #325 Signed-off-by: Pavan Pss <[email protected]> Co-authored-by: Christian Kadner <[email protected]>
1 parent ef85c69 commit fe965be

File tree

3 files changed

+78
-18
lines changed

3 files changed

+78
-18
lines changed

api/README.md

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,59 @@
1-
# Machine Learning Exchange API - Python Client and Python-Flask Server
1+
# MLX API - Python Client and Python-Flask Server
22

3-
An extension to the Kubeflow Pipeline API for Components and Models
3+
The MLX API is an extension to the Kubeflow Pipeline API with additional API
4+
endpoints for Dataset, Models, Notebooks and Pipeline Components.
5+
We use [OpenAPI v2 (fka Swagger)](https://swagger.io/specification/v2/) for the
6+
[API specification](swagger/swagger.yaml).
47

5-
---
68

7-
# Quickstart
9+
# Deploy to Kubernetes
810

9-
## Deploy to Kubernetes
11+
If you already have a Kubeflow Pipelines deployment on a Kubernetes cluster, you
12+
can use the following steps to deploy the MLX API on top of it. However, for a full
13+
deployment of MLX we recommend following on of these [guides](../README.md#1-deployment)
1014

11-
kubectl apply -f ./server/mlx-api.yml
15+
1) Run kubectl command to apply the manifest
1216

13-
## Find API Server Host and Port
17+
`kubectl apply -f ./server/mlx-api.yml`
1418

15-
export API_HOST=$(kubectl get nodes -o jsonpath='{.items[].status.addresses[?(@.type=="ExternalIP")].address}')
16-
export API_PORT=$(kubectl get service mlx-api -n kubeflow -o jsonpath='{.spec.ports[0].nodePort}')
19+
2) Find API Server Host and Port
1720

18-
## Open the Swagger UI in a Web Browser
21+
`export API_HOST=$(kubectl get nodes -o jsonpath='{.items[].status.addresses[?(@.type=="ExternalIP")].address}')`
22+
`export API_PORT=$(kubectl get service mlx-api -n kubeflow -o jsonpath='{.spec.ports[0].nodePort}')`
1923

20-
open "http://${API_HOST}:${API_PORT}/apis/v1alpha1/ui/"
24+
3) Open the Swagger UI in a Web Browser
25+
26+
`open "http://${API_HOST}:${API_PORT}/apis/v1alpha1/ui/" `
2127

28+
2229
---
2330

24-
# Development Setup
31+
# API Development
32+
33+
## Code Generation Overview
34+
35+
![API Codegeneration Workflow](codegen_workflow.png)
36+
37+
- Changes/additions to the API are done in the API [spec](swagger/swagger.yaml)
38+
- The [`generate_code.sh`](generate_code.sh) script validates the API [spec](swagger/swagger.yaml)
39+
and generates [`client`](client) and [`server`](server) Python packages.
40+
The [examples](examples) package is hand-written based on the usage examples
41+
inside the `client` package
42+
- Instead of a static HTML documentation for the API endpoints, a Swagger UI web
43+
interface will be generated on the fly when the Python server is started
44+
- The API endpoints and the JSON data model is documented under [`client/docs`](client/docs)
45+
in Markdown format which works well when browsing through the GitHub repo
46+
- After the code generation, we need to copy any new API method stubs (if any new)
47+
from the [`server/swagger_server/controllers`](server/swagger_server/controllers) folder
48+
to the [`server/swagger_server/controllers_impl`](server/swagger_server/controllers_impl)
49+
folder and implement the actual business logic
50+
- If existing API method signatures got updated, we need to update the existing
51+
`controller_impl` methods respectively
52+
2553

26-
## Swagger Codegen 2.4
54+
## Development Setup
55+
56+
### Swagger Codegen 2.4
2757

2858
To generate our API we are using [`swagger-codegen`](https://github.com/swagger-api/swagger-codegen/tree/v2.4.8#prerequisites)
2959
version [`2.4`](https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.8/swagger-codegen-cli-2.4.8.jar)
@@ -48,20 +78,29 @@ will automatically download the _"correct"_ version of the `swagger-codegen-cli.
4878
# brew install swagger-codegen@2
4979
# brew link --force swagger-codegen@2
5080

51-
## Create a Python Virtual Environment for Development
81+
### Create a Python Virtual Environment for Development
5282

5383
python3 -m venv .venv
5484
source .venv/bin/activate
5585

56-
## Install the Python Package Dependencies
86+
### Install the Python Package Dependencies
5787

5888
# cd <mlx_root_dir>
5989
# cd api
6090

6191
pip install -r ./requirements.txt
6292

93+
94+
6395
## (Re-)Generate Swagger Client and Server Code
6496

97+
If there are changes to the [API spec](swagger/swagger.yaml) then we need to re-
98+
generate the API client and server code. Do not run the script `codegen.sh`
99+
on its own, since Swagger generates a lot of unwanted and some breaking changes.
100+
Instead use the [generate_code.sh](generate_code.sh) script which runs the Swagger
101+
codegen and tries to undo some of the code and documentation changes that are not
102+
desired.
103+
65104
./generate_code.sh
66105

67106
## Build the Docker Image
@@ -86,7 +125,8 @@ or:
86125
kubectl delete -f ./server/mlx-api.yml
87126
kubectl apply -f ./server/mlx-api.yml
88127

89-
## Testing API Code Changes with Docker Compose
128+
129+
## Testing API Code Changes Locally with Docker Compose
90130

91131
You can test most code changes without a Kubernetes cluster. A K8s cluster is only
92132
required to `run` the generated sample pipeline code. Running the Quickstart with
@@ -189,3 +229,7 @@ Docker Compose stack with the `-v` option (`docker compose --project-name no_api
189229
-d @catalog_upload.json \
190230
http://localhost:8080/apis/v1alpha1/catalog
191231

232+
# Troubleshooting
233+
234+
Report any issues with at https://github.com/machine-learning-exchange/mlx/issues
235+

api/codegen_workflow.png

30.6 KB
Loading

api/server/README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1-
# Swagger generated server
1+
# MLX API Server
22

33
## Overview
4-
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen)
4+
5+
The MLX API server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen)
56
project. By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote
67
server, you can easily generate a server stub. This is an example of building a Swagger-enabled
78
Flask server.
89

910
This example uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask.
1011

12+
## MLX API Server Modules
13+
14+
| Python package/script | Purpose |
15+
| ------------- | ------------- |
16+
| `code_templates` | Code templates are used to generate sample Kubeflow pipeline DSL scripts for each asset type |
17+
| `controllers` | Controllers are the code stubs (“interfaces”) for the API endpoints generated by Swagger |
18+
| `controllers_impl` | Controller implementation of the generated API code stubs (“interfaces”), originally copied from respective controller and then filled in with the actual business logic. API calls get forwarded from the `controllers` to the `controllers_impl` by injection of some code magic in `util.py` (see `codegen.sh`) |
19+
| `data_access` | Contains 2 clients - MySQL (relational database) and Minio (object storage) for data access |
20+
| `gateways` | Connects the API server to various services on the Kubernetes cluster like KFServing, Kubeflow Pipelines, and the Kubernetes API |
21+
| `models` | Swagger generated API classes used to transfer data between API client and API server |
22+
| `encoder.py` | Implementation of JSON encoder (generated by Swagger) |
23+
| `util.py` | Collection of helper functions, most notably to “glue” the API `controllers` code stubs to the `controllers_impl` API implementations |
24+
1125
## Requirements
26+
1227
Python 3.6.1+
1328

1429
## Usage
@@ -33,6 +48,7 @@ http://localhost:8080/apis/v1alpha1/swagger.json
3348
```
3449

3550
To launch the integration tests, use tox:
51+
3652
```
3753
sudo pip install tox
3854
tox

0 commit comments

Comments
 (0)