Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
.idea

# Python
*.pyc
*.swp
__pycache__
23 changes: 23 additions & 0 deletions backend/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.PHONY: clean run build-docker

NAME = $(shell grep "LABEL name" docker/Dockerfile | cut -d"=" -f2 | sed 's/\"//g')
VERSION = $(shell grep "LABEL version" docker/Dockerfile | cut -d"=" -f2 | sed 's/\"//g')

help:
@echo "\033[32m.: HELP :."
@echo "==========\033[0m"
@echo " - clean clean *.pyc file"
@echo " - run run Flask app"
@echo " - build-docker build docker image => $(NAME):$(VERSION)"


clean:
@find . -type f -name "*.pyc" -delete

run: export FLASK_ENV = dev
run:
@gunicorn -w 2 -b 0.0.0.0:5000 run:app --log-level debug

build-docker:
@cp -a Makefile __init__.py api data.csv instance requirements.txt run.py docker/
@docker build docker/ -t $(NAME):$(VERSION)
127 changes: 127 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Backend

Backend is a python Flask application

## Requirements

```
* Python (>= 3.4)
* docker (only for dev purposes)
```

## Installation

### Clone this repository

```
bzhtux@localhost: ~# git clone -b poc-backend-python https://github.com/jfmou/interactionsGraph.git
```
If you already have cloned this repository just point it to poc-backend-python branch:

```
bzhtux@localhost: ~# git fetch --all
bzhtux@localhost: ~# git checkout poc-backend-python
```

### Native install

I suggest you to use a virtualenv to run this python app. To create a virtualenv with python3 just run:

```
bzhtux@localhost: ~# mkdir -p ~/.venvs
bzhtux@localhost: ~# python3 -m venv ~/.venvs/interGraph
```

To use this virtualenv, run:

```
bzhtux@localhost: ~# source ~/.venvs/interGraph/bin/activate
(interGraph) bzhtux@localhost: ~#
```

Now go back to your git workspace and install python dependancies:

```
(interGraph) bzhtux@localhost: ~# cd Workdir/Python3x/interactionsGraph
(interGraph) bzhtux@localhost: interactionsGraph# pip install -r backend/requirements.txt
```
That's all for native installation step!

### Docker install

Docker installation is very simple:

* [Build](#Build) docker image


## Build

To build docker image, you can use Makefile provided with this command:

```
bzhtux@localhost: ~# make build-docker
```

## Run

### Native

```
bzhtux@localhost: ~# make run
```

### Docker

Use `-ti` for interactive console:

```
bzhtux@localhost: ~# docker run -ti --rm -p 5000:5000 ig-backend-dev:0.0.1 bash
```

## Usage

You can call the backend API without any Auth like this curl command:

```
curl -sL -k http://0.0.0.0:5000/api/datas | jq
```

## Development

### Organization

```
bzhtux@localhost: ~# tree -I "__pycache__"
.
├── Makefile
├── README.md
├── __init__.py
├── api
│   ├── __init__.py
│   ├── commons.py
│   ├── models.py
│   └── views
│   ├── __init__.py
│   └── default.py
├── data.csv
├── docker
│   ├── Dockerfile
│   ├── entrypoint.sh
├── instance
│   ├── dev.py
│   ├── prod.py
│   └── test.py
├── requirements.txt
└── run.py
```
* **api** folder: all python files required by API
* **instance** folder: configuration folder, each file for a dedicated env
* **docker** folder: files required to build docker image (makefile copy required python files into docker directory before building the image)
* **api/views** folder: really ??? Yes API views ('/api/blabla')
* **requirements.txt** file: python dependancies

### TODO

* write a bunch of tests
* write some qa/ci enforcements
* validate this poc ;-)
Empty file added backend/__init__.py
Empty file.
31 changes: 31 additions & 0 deletions backend/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from api.commons import Utils
from flask import Flask
import os
import sys

sys.path.append(os.path.abspath(os.curdir))
app = Flask(__name__, instance_relative_config=True)

# Try to get env from SHELL ENV
# Set to 'prod' by default
try:
env = os.environ['FLASK_ENV']
except Exception as e:
print("+++ Error loading env: %s" % e)
print("+++ Setting env to default: production")
env = "prod"

print("\033[32mENV: %s\033[0m" % env)

# Load the config file regarding env above
if env == "dev":
app.config.from_pyfile('dev.py')
if env == "test":
app.config.from_pyfile('test.py')
if env == "prod":
app.config.from_pyfile('prod.py')

try:
import api.views
except Exception as e:
print("init.imports.except: %s" % e)
49 changes: 49 additions & 0 deletions backend/api/commons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import csv
#import json


class Utils():

def __init__(self):
self.COLORS = {'OK': '#00ff00',
'Moyen': '#ff9900',
'Pas d\'interaction': '#999',
'NOK': '#ff0000',
'DEFAULT': '#fff'
}

def read_csv_file(self, csv_file_path):
csv_data = list()
with open(csv_file_path) as csv_fd:
csvdata = csv.DictReader(csv_fd, delimiter=',')
for row in csvdata:
csv_data.append(row)
return csv_data

def build_nodes_id_from_csv(self, nodes):
nodes_id = [node['id'] for node in nodes]
return nodes_id

def build_nodes_from_csv(self, csv_data):
#data = self.read_csv_file("./data.csv")
nodes = list()
for row in csv_data:
if row['↓ pense que ses relations avec → sont'] not in nodes:
nodes.append({"id": row["↓ pense que ses relations avec → sont"], "group": ""})
return nodes

def build_links_from_csv(self, csv_data):
links = list()
for row in csv_data:
# print("> %s\n" % row['↓ pense que ses relations avec → sont'])
source = row['↓ pense que ses relations avec → sont']
for item in row:
if row['↓ pense que ses relations avec → sont'] != row[item] and row['↓ pense que ses relations avec → sont'] != item:
# print(" - %s : %s" % (item, row[item]))
target = item
try:
value = self.COLORS[row[item]]
except:
value = self.COLORS['DEFAULT']
links.append({"source": source, "target": target, "value": value})
return links
Empty file added backend/api/models.py
Empty file.
1 change: 1 addition & 0 deletions backend/api/views/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from api.views import default
24 changes: 24 additions & 0 deletions backend/api/views/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from api import app
from api.commons import Utils
from flask import jsonify

utils = Utils()


@app.route("/", methods=['GET'])
def index():
rows = utils.read_csv_file("./data.csv")
return jsonify({"rows": rows}), 200


@app.route("/api", methods=['GET'])
def index_api():
rows = utils.read_csv_file("./data.csv")
return jsonify({"rows": rows}), 200

@app.route("/api/datas", methods=['GET'])
def get_json_data():
csv_data = utils.read_csv_file("./data.csv")
nodes = utils.build_nodes_from_csv(csv_data)
links = utils.build_links_from_csv(csv_data)
return jsonify({"nodes": nodes, "links": links}), 200
21 changes: 21 additions & 0 deletions backend/data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
↓ pense que ses relations avec → sont,Inter,Bleu,Culture,Musique,FIP Mouv C&Co,Echoes,Mobiwan /*,Wanda Indus,Wanda Hosting,Otto,Zone 51,Cockpit,Cruiser API,QA,SEO,CRM,Partenariats,Design,Innovation,Acquisition
Inter,,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,OK,Moyen,Pas d'interaction,OK,OK,Moyen,OK,Moyen,Moyen,OK,Pas d'interaction,Pas d'interaction
Bleu,OK,,OK,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,Pas d'interaction,Moyen,Moyen,Moyen,Moyen,Moyen,Pas d'interaction,Moyen,Pas d'interaction,Moyen
Culture,OK,OK,,OK,Pas d'interaction,Pas d'interaction,OK,OK,Moyen,Moyen,Pas d'interaction,OK,OK,OK,NOK,Pas d'interaction,Pas d'interaction,Moyen,Pas d'interaction,Pas d'interaction
Musique,OK,Pas d'interaction,Pas d'interaction,,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,OK,OK,OK,OK,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction
FIP Mouv C&Co,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,,OK,Pas d'interaction,OK,OK,OK,OK,OK,OK,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,OK,Moyen,Pas d'interaction
Echoes,OK,Pas d'interaction,Pas d'interaction,OK,OK,,OK,Moyen,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,Moyen,OK,Pas d'interaction,Moyen,OK,Moyen,Pas d'interaction
Mobiwan /*,Moyen,OK,Pas d'interaction,Pas d'interaction,OK,OK,,OK,Pas d'interaction,Pas d'interaction,OK,OK,Moyen,OK,OK,Pas d'interaction,OK,OK,Moyen,Moyen
Wanda Indus,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,NOK,NOK,,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,Pas d'interaction,Pas d'interaction
Wanda Hosting,OK,OK,OK,OK,Pas d'interaction,OK,Pas d'interaction,OK,,OK,OK,OK,OK,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction
Otto,Moyen,OK,OK,NOK,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,OK,,Pas d'interaction,OK,OK,OK,OK,Pas d'interaction,Pas d'interaction,NOK,Pas d'interaction,Pas d'interaction
Zone 51,OK,OK,OK,Moyen,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,Pas d'interaction,,OK,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction
Cockpit,OK,OK,OK,Moyen,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,NOK,Moyen,OK,,Moyen,OK,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Moyen,Pas d'interaction
Cruiser API,OK,OK,OK,Pas d'interaction,OK,OK,Moyen,OK,Moyen,Pas d'interaction,OK,Pas d'interaction,,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction
QA,Moyen,OK,OK,OK,Pas d'interaction,Moyen,Moyen,OK,Moyen,OK,OK,OK,Pas d'interaction,,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction
SEO,Moyen,OK,OK,Moyen,Moyen,OK,OK,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,OK,Pas d'interaction,OK,,OK,Moyen,OK,Moyen,OK
CRM,Moyen,OK,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction
Partenariats,OK,OK,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,,OK,OK,OK
Design,Moyen,OK,OK,OK,OK,OK,OK,Moyen,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,OK,Pas d'interaction,,OK,NOK
Innovation,OK,Pas d'interaction,Pas d'interaction,OK,OK (webradios) / Pas bien (Hyperradio),Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,OK,,Pas d'interaction
Acquisition,OK,OK,Pas d'interaction,OK,OK,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,Pas d'interaction,OK,Pas d'interaction,
Loading