Skip to content

cringeops/pystringer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pystringer project

Description

  • This is a hello-world containerized Flask app that expects a string in POST payload and responds with a result pretty much like a CLI utility.
  • It comes with Grafana requests’ gragh.
  • NB! There are some bad design decisions for the sake of simplicity (e.g. putting monitoring and the app itself into a single pod).
  • Also, a production-grade app must use ingress instead of NodePort.
  • Also, a good nginx configuration must ensure invalid requests can’t even reach the app.
  • Also, a nice project would have a CI pipeline to test Dockerfile build, run unit and monitoring testing, and deploy the thing somewhere. Yet, it’s just a dumb string manipulation app.

Deployment

docker-compose

  • The service is deployed at localhost by default.
  • Port 80 is served by nginx.
  • Grafana is available at http://127.0.0.1/grafana with admin:admin login pair.
  • Grafana provides total request count graph in pystringer dashboard.
### from the project root
$ docker-compose up -d

Kubernetes + Minikube

  • Minikube assigns random IPs and ports for external services.
  • Minikube instance should be running upon deployment.
  • Grafana is available at http://$MINIKUBE_SERVICE_IP:PORT/grafana/login
### start minikibe
$ minikube start

### inject Docker envs to minikube instance
### to enable locally built image discovery
$ eval $(minikube -p minikube docker-env)

### build pystringer image
$ docker build -t pystringer -f ./docker/Dockerfile.app .

### deploy the app
$ kubectl apply -f ./k8s

### wait until the pod is operational
$ kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
pystringer-dep-7d65d4b4d6-gbgxn   4/4     Running   0          79s

### expose the service
$ minikube service pystringer-service

### get the URL
$ minikube service --all
😿  service default/kubernetes has no node port
|-----------|--------------------|--------------|---------------------------|
| NAMESPACE |        NAME        | TARGET PORT  |            URL            |
|-----------|--------------------|--------------|---------------------------|
| default   | kubernetes         | No node port |
| default   | pystringer-service |           80 | http://192.168.49.2:31527 |
|-----------|--------------------|--------------|---------------------------|

### run unit testing
$ PYSTRINGER_URL=http://192.168.49.2:31527 python3 app_test.py

Helm + Minikube

  • It is quite similar to k8s deployment.
### start minikube
$ minikube start

### export minikube envs
$ eval $(minikube -p minikube docker-env)

### build the Docker image
$ docker build -t pystringer -f ./docker/Dockerfile.app .

### deploy the chart
$ helm install pystringer pystringer-helm

### get the service URL
$ minikube service --all
😿  service default/kubernetes has no node port
|-----------|--------------------|--------------|---------------------------|
| NAMESPACE |        NAME        | TARGET PORT  |            URL            |
|-----------|--------------------|--------------|---------------------------|
| default   | kubernetes         | No node port |
| default   | pystringer-service |           80 | http://192.168.49.2:32427 |
|-----------|--------------------|--------------|---------------------------|

### run unit testing
$ PYSTRINGER_URL=http://192.168.49.2:32427 python3 app_test.py

Usage

  • By default on docker-compose deployment, nginx frontend listens on 127.0.0.1:80 and forwards requests to uWSGI running in a separate container.
  • Make sure you have curl installed.
### get list of valid requests
$ curl http://127.0.0.1                            
Valid requests: lowercase, uppercase, reverse, randomcase

### convert a string to lowercase
$ curl -d 'LOREM IPSUM DOLOR SIT AMET' http://127.0.0.1/lowercase                                                                       
lorem ipsum dolor sit ame

### convert a string to uppercase
$ curl -d 'lorem ipsum dolor sit ame' http://127.0.0.1/uppercase
LOREM IPSUM DOLOR SIT AME

### convert a string to randomcase (that's my favorite)
$ curl -d 'lorem ipsum dolor sit ame' http://127.0.0.1/randomcase
loReM ipsuM DOloR SIt AME

### reverse a string
$ curl -d 'lorem ipsum dolor sit ame' http://127.0.0.1/reverse   
ema tis rolod muspi merol

Testing

  • Unit testing is implemented as a simple infinite loop that selects a method randomly on each iteration, generates a random string, and asserts against a known result.
  • Also, it’s quite useful to populate metrics with some data.
  • You may optionally provide a URL via PYSTRINGER_URL enivornment variable.
### make sure you have requests module installed
$ python3 app_test.py
randomcase: cfrrxczxrpblfailvgilbaljpcststqfhcjwdvyfb
response: cfrRxCZXrpbLFAiLVGilBALjpCSTSTQFhcjwdVyFB
**************************************************
lowercase: dbrgkrktghz
response: dbrgkrktghz
**************************************************
...

About

A containerized hello-world Flask app

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published