https://github.com/fbjorn/test-healthcheck
Test task before an interview
https://github.com/fbjorn/test-healthcheck
Last synced: 2 months ago
JSON representation
Test task before an interview
- Host: GitHub
- URL: https://github.com/fbjorn/test-healthcheck
- Owner: fbjorn
- Created: 2020-06-29T12:37:06.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-06-03T22:46:18.000Z (over 3 years ago)
- Last Synced: 2024-12-28T11:13:59.788Z (9 months ago)
- Language: Python
- Size: 20.5 KB
- Stars: 0
- Watchers: 1
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# test-healthcheck
Test task before an interview## Task description:
Implement URL healthcheck service using pythonApplication should be started with the following params:
- interval – Polling interval (seconds)
- urls – List of URLs to check"Healthcheck" means that HTTP GET request to the URL responds with
successful status code.All checks are stored in the database - date, URL, status.
There also should be a public API with a single endpoint:
`/status` – All the data about checks from the DB, encoded as JSON
Technical requirements:
- PostgreSQL
- Python
- All services (including the DB) are wrapped into Docker container
- All services are managed via `docker-compose`## Project structure
- `backend` – Public API for listing statuses. Written using `bottle` (cause it's
deadly simple server) and `SQLAlchemy`
- `worker` – Application for URLs polling. Written using `asyncio` and `asyncpg`
- `pg-init-scripts` – PostgreSQL helpers for bootstrapping multiple databasesThere are 2 services which work with the common DB. To avoid any schema synchronization
problems, `backend` is the app responsible for tables bootstrapping as well as database
migrations. `worker` app is simply depends on the `backend` and starts only after backend
is started (and therefore after database is ready).#### Pre-commit hooks
There are some [pre-commit](https://pre-commit.com/) hooks configured per this project.
To install them:
```shell script
pre-commit install-hooks
```## Configuration
Configuration is achieved via .env file. After project checkout, create a copy
of `.env.tmpl` and call it `.env`.
```shell script
cp .env.tmpl .env
```
Modify it by your needs. All parameters should be self-explanatory.## How to run
Make sure to [configure](#Configuration) `.env` file.
There are 2 docker-compose configuration files. To run service in production:
```bash
docker-compose up
```Then check everything works as expected:
```shell script
curl localhost:8080/status
[
{
"ok": false,
"code": 404,
"elapsed": 0.439211,
"date": "2020-07-02T11:41:07.029079",
"url": "https://github.com/oops/mistake"
},
{
"ok": true,
"code": 200,
"elapsed": 0.713434,
"date": "2020-07-02T11:41:07.291180",
"url": "https://getsitecontrol.com"
}
]
```To run service in local (development) mode:
```bash
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml up
```In the development mode:
- Debug is on by default
- Code sources are mounted as volumes
- Additional python libraries are installed (e.g `pytest`, `flake8` and `isort`)
- PostgreSQL creates different database (and one more for unit tests)
- Dockerfile has more user-friendly layers in terms of rebuilding## Tests
There are unit tests written for both backend and worker apps. To run them:
```shell script
# Backend
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml run --rm backend pytest# Worker
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml run --rm worker pytest
```Also you can run flake8 & mypy checks as:
```shell script
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml run --rm invoke check
```Or both linters and tests:
```shell script
docker-compose -f docker-compose.yaml -f docker-compose.dev.yaml run --rm invoke test
```## TO-DOs
(Or better to say ways of improvements which intentionally were omitted cause
it's a test task, not a prod-ready app)- Move some duplicated code into a shared python library
- Add migrations
- Set up CI
- Fix elapsed time, cause now it includes time for switching context