Skip to content

Commit

Permalink
chore(iatlas): migrate iAtlas API project to an Nx project (ARCH-339) (
Browse files Browse the repository at this point in the history
  • Loading branch information
tschaffter authored Dec 10, 2024
1 parent 7849b72 commit 8fec342
Show file tree
Hide file tree
Showing 31 changed files with 1,134 additions and 143 deletions.
10 changes: 7 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
}
},
"forwardPorts": [
2432, 3000, 3306, 3333, 4200, 4211, 5200, 5432, 5601, 7010, 7443, 7200, 7888, 8010, 8071, 8000,
8080, 8081, 8082, 8084, 8085, 8086, 8090, 8200, 8443, 8888, 8889, 9090, 9104, 9200, 9411, 27017,
18080
2432, 3000, 3306, 3333, 4200, 4211, 5000, 5200, 5432, 5601, 7010, 7443, 7200, 7888, 8010, 8071,
8000, 8080, 8081, 8082, 8084, 8085, 8086, 8090, 8200, 8443, 8888, 8889, 9090, 9104, 9200, 9411,
27017, 18080
],
"portsAttributes": {
"2432": {
Expand All @@ -97,6 +97,10 @@
"label": "nx graph",
"onAutoForward": "silent"
},
"5000": {
"label": "iatlas-api",
"onAutoForward": "silent"
},
"5432": {
"label": "openchallenges-postgres",
"onAutoForward": "silent"
Expand Down
9 changes: 9 additions & 0 deletions apps/iatlas/api/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FLASK_APP=iatlasapi.py
FLASK_ENV=development
FLASK_RUN_PORT=5000
POSTGRES_DB=iatlas
POSTGRES_HOST=iatlas-postgres
POSTGRES_PORT=5432
POSTGRES_PASSWORD=postgres
POSTGRES_USER=changeme
SNAKEVIZ_PORT=8020
1 change: 1 addition & 0 deletions apps/iatlas/api/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.8.20
41 changes: 35 additions & 6 deletions apps/iatlas/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
# Start with a bare Alpine Linux to keep the container image small
FROM tiangolo/uwsgi-nginx-flask:python3.8
FROM python:3.8.20-slim-bullseye

WORKDIR /app
COPY . /app
ENV APP_DIR=/opt/app

# Install the PyPI dependencies using pip
RUN pip3 install --no-cache-dir -r requirements.txt
RUN apt-get update -qq -y && export DEBIAN_FRONTEND=noninteractive \
&& apt-get install --no-install-recommends -qq -y \
# Required to install uWSGI
build-essential \
# Used in docker-entrypoint.sh
gosu \
&& apt-get -y autoclean \
&& apt-get -y autoremove \
&& rm -rf /var/lib/apt/lists/*

WORKDIR ${APP_DIR}
COPY api ./api
COPY pyproject.toml poetry.lock iatlasapi.py config.py uwsgi.ini ./

# Install the app dependencies.
# Install the version of Poetry used inside the dev container.
# See /workspaces/sage-monorepo/tools/devcontainers/sage/.devcontainer/Dockerfile
RUN pip install --no-cache-dir poetry==1.8.3 \
&& poetry config --local virtualenvs.create false \
&& poetry install --with prod --no-root --no-interaction --no-ansi \
&& pip cache purge \
&& chown -R www-data:www-data ${APP_DIR}

WORKDIR /
COPY docker-entrypoint.sh .
RUN chmod +x docker-entrypoint.sh

EXPOSE 5000

ENTRYPOINT ["/docker-entrypoint.sh"]

# Run production server
CMD ["uwsgi", "--ini", "uwsgi.ini", "--lazy", "--http", ":5000"]
127 changes: 30 additions & 97 deletions apps/iatlas/api/README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,54 @@
# iAtlas API

A GraphQL API that serves data from the iAtlas Data Database. This is built in Python and developed and deployed in Docker.
A GraphQL API that serves data from the iAtlas Data Database. This is built in Python and developed
and deployed in Docker.

## Status
## Usage

### Staging
Show the tasks available to this project:

[![coverage report](https://gitlab.com/cri-iatlas/iatlas-api/badges/staging/coverage.svg?style=flat)](https://cri-iatlas.gitlab.io/iatlas-api/)

## Dependencies

- [Docker Desktop](https://www.docker.com/products/docker-desktop) (`docker`)
- [Visual Studio Code](https://code.visualstudio.com/) (`code`) - this is optional, but sure makes everything a lot easier.

## Development

The instructions below assume that there is a PostgreSQL server running locally with the iAtlas Database installed (see [iAtlas-Data](https://gitlab.com/cri-iatlas/iatlas-data)). If this is not the case, please see information on [running PostgreSQL in Docker](#running-postgres-in-docker) below.

To change any of the environment variables used by the app see [Environment Variables](#environment-variables) below.

The first time you checkout the project, run the following command to build the docker image, start the container, and start the API:

```sh
./start.sh
```console
nx show project iatlas-api
```

This will build the Docker image and run the container. Once the container is created, the Flask server will be started.

The GraphiQL playground interface should open automatically in your browser.

**Note:** If you get _'Version in "./docker-compose.yml" is unsupported.'_, please update your version of Docker Desktop.
## Create the project configuration file

**Optional:** If you choose to use VS Code, you can use the [Dev-Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension to develop from within the container itself. Using this approach, you don't need to install Python or any dependencies (besides Docker and VS Code itself) as everything is already installed inside the container. There is a volume mapped to your user .ssh folder so that your ssh keys are available inside the container as well as your user .gitconfig file. The user folder inside the container is also mapped to a volume so that it persists between starts and stops of the container. This means you may create a .bash_profile or similar for yourself within the container and it will persist between container starts and stops.

The following command will stop the server and container:

```sh
./stop.sh
```console
nx create-config iatlas-api
```

Restart the container with the following command:
## Prepare the Python environment

```sh
./start.sh
```console
nx prepare iatlas-api
```

If there are changes made to the container or image, first, stop the container `./stop.sh`, then rebuild it and restarted it with `./start.sh --build` or `./start.sh -b`.

Remote into iatlas-dev container.

Open the workspace by file -> Open workspace from file -> /project/iatlas-api.code-workspace

### Non-Dockerized

If you choose NOT to use the dockerized development method above, please ensure the following are installed:

- [Python](https://www.python.org/) - version 3.8
- All the packages in the [`requirements.txt`](./requirements.txt) file at the versions specified.
- All the packages in the [`requirements-dev.txt`](./requirements-dev.txt) file at the versions specified.

See [https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/) for information on installing Python packages for a specific project.
## Build the Docker image

Start the app with the following called from the root of the project. (Please note the dot(`.`) at the very beginning of the command. This will "source" the script.):

```sh
. set_env_variables.sh && python run.py
```console
nx build-image iatlas-api
```

### Running Postgres in Docker

A simple way to get PostgreSQL running locally is to use Docker. Here is a simple Dockerized PostgreSQL server with pgAdmin:

["postgres_docker" on Github](https://github.com/generalui/postgres_docker)

#### Linux ONLY

If you are running on a Linux operating system the default connection to the docker container `host.docker.internal` will not work. To connect to the local dockerized PostgreSQL DB, ensure there is a `.env-dev` file ([`.env-SAMPLE`](./.env-SAMPLE) can be used as a reference.) In the `.env-dev` file, ensure the `POSTGRES_HOST` variable is set to `172.17.0.1`
## Start the API with Docker Compose

```.env-dev
POSTGRES_HOST=172.17.0.1
```console
nx serve-detach iatlas-api
```

### Connecting to a different Database
## Open the GraphQL Playground

Alternatively, the app may be set up to connect to the existing staging database or another database.
To access the GraphQL Playground, open your browser and navigate to:

To connect to a different database (ie staging), the `.env-dev` file must also be used with values similar to:
`http://http://localhost:5000/graphiql`

```.env-dev
POSTGRES_DB=iatlas_staging
POSTGRES_HOST=iatlas-staging-us-west-2.cluster-cfb68nhqxoz9.us-west-2.rds.amazonaws.com
POSTGRES_PASSWORD={Get_the_staging_password}
POSTGRES_USER=postgres
```

### Environment Variables
Use the query shown below to test the API or use one included in `./example_queries`.

All the environment variables used by the app have defaults. To set the environment variables, simply run the following bash script from the root of the project. (Please note the dot(`.`) at the very beginning of the command. This will "source" the script.):

```sh
. set_env_variables.sh
```json
{
__schema {
queryType {
name
}
}
}
```

The default environment variables' values may be over-written by adding the value to a `.env-dev` file in the root of the project. This file is not versioned in the repository.

The [`.env-SAMPLE`](./.env-SAMPLE) file is an example of what the `.env-dev` could be like and may be used as a reference.

## Testing

All tests are in the [`tests/`](./tests/) folder.

See: [TESTING.md](./tests/TESTING.md) in the [`tests/`](./tests/) folder

## Performance Profiling

See: [PROFILING.md](./api/telemetry/PROFILING.md) in the [`api/telemetry/`](./api/telemetry/) folder

## Logging

See: [LOGGING.md](./api/logger/LOGGING.md) in the [`api/logger/`](./api/logger/) folder
9 changes: 9 additions & 0 deletions apps/iatlas/api/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -e

if [ "$1" = 'uwsgi' ] || [ "$1" = 'python' ]; then
cd ${APP_DIR}
exec gosu www-data "$@"
fi

exec "$@"
13 changes: 13 additions & 0 deletions apps/iatlas/api/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash

PYTHON_VERSION="3.8.20"

pyenv install --skip-existing $PYTHON_VERSION

# Initializing pyenv again solves an issue encountered by GitHub action where the version of Python
# installed above is not detected.
eval "$(pyenv init -)"

pyenv local $PYTHON_VERSION
poetry env use $(pyenv which python)
poetry install --with dev
Loading

0 comments on commit 8fec342

Please sign in to comment.