Skip to content

Commit 5d86e13

Browse files
committed
Initial Commit
0 parents  commit 5d86e13

File tree

10 files changed

+268
-0
lines changed

10 files changed

+268
-0
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
4+
# Environments
5+
venv/
6+
7+
# PyCharm IDE
8+
.idea/

README.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
2+
Hana to Python Application
3+
===================
4+
5+
The purpose of this project is to implement a simple Python application to demonstrate the integration between a common third party application to a SAP Hana database.
6+
7+
> **Note:**
8+
>
9+
> - This project is directly linked to the project at the [HanaService](https://github.com/NickChecan/HanaService) repository.
10+
> - Project developed with Python 3.7.
11+
12+
13+
----------
14+
15+
Project Components
16+
-------------
17+
18+
This project uses the [Flask](http://flask.pocoo.org/) framework to serve data through a simple web site platform locally.
19+
20+
```
21+
HanaToPython-Application
22+
├── app
23+
│ ├── modules
24+
│ │ ├── Controller.py
25+
│ │ ├── Model.py
26+
│ │ └── __init__.py
27+
│ ├── templates
28+
│ │ └── index.html
29+
│ └── __init__.py
30+
├── config.py
31+
├── requirements.txt
32+
└── run.py
33+
```
34+
35+
The routes used in this application can be found at **./app/modules/Controller.py**.
36+
37+
The **.app/modules/Model.py** file will be responsible to access the Hana data through a database connection established by the information provided at the **config.py** file.
38+
39+
The template folder will handle all views available for the application.
40+
41+
The file **requirements.txt** contains all the plugins used for the current application and the **run.py** file will be responsible for the application execution.
42+
43+
44+
----------
45+
46+
Getting Started
47+
-------------
48+
49+
Before importing this project to your Python workspace, it is necessary to make sure the prerequisites steps are properly done in your development environment.
50+
The installation procedure described in this documentation will assume you've already have Python installed at your computer.
51+
52+
#### <i class="icon-layers"></i> Prerequisites
53+
54+
- Hana Service </br>
55+
To execute this application it will be necessary to properly deploy the [Hana Service](https://github.com/NickChecan/HanaService) project into your Hana Trial environment.
56+
57+
- A Python Editor of your choice </br>
58+
For this project the [PyCharm](https://www.jetbrains.com/pycharm/) IDE and [Visual Studio Code](https://code.visualstudio.com/) was used for development, but the same is not required to correctly deploy the application it self.
59+
60+
- Install the virtual environment package </br>
61+
**Virtual Environment** (virtualenv) is a tool to create isolated Python environments. The *virtualenv* command creates a folder which contains all the necessary executables to use the packages that a Python project would need. The same can be installed as described in [this link](http://docs.python-guide.org/en/latest/dev/virtualenvs/) through the following command:
62+
63+
```
64+
$ pip install virtualenv
65+
```
66+
67+
68+
#### <i class="icon-download"></i> Installing
69+
70+
The steps bellow will guide you through the project installation. </br>
71+
The following commands should be executed in your computer console at the project folder:
72+
73+
* Clone the project to your local repository workspace;
74+
75+
* Create a virtual environment for the imported application through the following command:
76+
```
77+
$ virtualenv <Virtual Environment name>
78+
```
79+
* Activate your virtual environment with the command:
80+
```
81+
$ <Virtual Environment name>\Scripts\activate
82+
```
83+
* With the virtual environment properly activated, install the plugins available at the **requirements.txt** file through the command:
84+
```
85+
$ pip install -r requirements.txt
86+
```
87+
This process should enable your application to be deployed in a local server for test purpose.
88+
89+
90+
> **Note:**
91+
>
92+
> - With the [Hana Service](https://github.com/NickChecan/HanaService) properly deployed, the **config.py** file should be modified to attend the address of your Hana Trial Instance.
93+
94+
95+
----------
96+
97+
Deployment
98+
-------------
99+
100+
With the Hana Service properly deployed, the **config.py** file modified to attend your Hana Trial Instance and the virtual environment activated, the python application should run through the following command:
101+
102+
```
103+
$ python run.py
104+
```
105+
106+
The same will enable the project to be accessed by you web browser trough a URL displayed by the mentioned command execution.
107+
108+
> **Tips:**
109+
>
110+
> - As mentioned in the Hana Service project repository, always remember to make sure the Hana Trial Instance is up and running through the Cloud Platform Cockpit before execute commands or test any application directly linked to the Hana Service.
111+
112+
113+
114+
Acknowledgments
115+
-------------
116+
This project was made possible thanks to the Flask framework tutorials available at the [Tutorials Point](https://www.tutorialspoint.com/flask/) and at [Bruno Rocha](http://brunorocha.org/) personal blog. These two web sites was incredibly helpful in the development and preparation step of this project.

app/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

app/modules/Controller.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import json
2+
from flask import Blueprint
3+
from app.modules.Model import Model
4+
5+
model = Model()
6+
controller = Blueprint('controller', "HanaToPython")
7+
8+
9+
@controller.route("/api/getRegions")
10+
def get_regions():
11+
return json.dumps(model.get_regions), 200, {"Content-Type": "application/json"}
12+
13+
14+
@controller.route("/api/getProducts")
15+
def get_products():
16+
return json.dumps(model.get_products), 200, {"Content-Type": "application/json"}
17+
18+
19+
@controller.route("/api/getSalesData")
20+
def get_sales_data():
21+
return json.dumps(model.get_sales_data), 200, {"Content-Type": "application/json"}
22+

app/modules/Model.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import pyhdb
2+
from config import Hana
3+
4+
5+
class Model(object):
6+
7+
connection = None
8+
9+
def __init__(self):
10+
self.connection = pyhdb.connect(Hana.HOST, Hana.PORT, Hana.USER, Hana.PASS)
11+
12+
@property
13+
def get_regions(self):
14+
regions_data = []
15+
cursor = self.connection.cursor()
16+
cursor.execute("SELECT * FROM \"SALES_TUTORIAL\".\"HanaService.CDSScripts::SalesDDL.Region\"")
17+
result_set = cursor.fetchall()
18+
for result in result_set:
19+
regions_data.append({"regionId": result[0],
20+
"regionName": result[1],
21+
"subRegionName": str(result[2])})
22+
return regions_data
23+
24+
@property
25+
def get_products(self):
26+
products_data = []
27+
cursor = self.connection.cursor()
28+
cursor.execute("SELECT * FROM \"SALES_TUTORIAL\".\"HanaService.CDSScripts::SalesDDL.Product\"")
29+
result_set = cursor.fetchall()
30+
for result in result_set:
31+
products_data.append({"productId": result[0],
32+
"productName": result[1]})
33+
return products_data
34+
35+
@property
36+
def get_sales_data(self):
37+
sales_data = []
38+
cursor = self.connection.cursor()
39+
cursor.execute("SELECT * FROM \"_SYS_BIC\".\"HanaService/SalesData\"")
40+
result_set = cursor.fetchall()
41+
for result in result_set:
42+
sales_data.append({"regionName": result[0],
43+
"productName": result[1],
44+
"salesAmount": str(result[2])})
45+
return sales_data
46+

app/modules/__init__.py

Whitespace-only changes.

app/templates/index.html

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!DOCTYPE html>
2+
<html lang="pt-br">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Hana 2 Python</title>
6+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
7+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
8+
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
9+
<script>
10+
$(document).ready(function () {
11+
12+
$.get("api/getSalesData", function (data) {
13+
console.log(data);
14+
for(var i = 0; i < data.length; i++) {
15+
$("#table tbody").append('<tr><td>' + data[i].regionName +
16+
'</td><td>' + data[i].productName +
17+
'</td><td>' + data[i].salesAmount + '</td>');
18+
}
19+
}, "json");
20+
21+
var link1 = "http://" + window.location.host + "/api/getRegions";
22+
$("#link1").attr("href", link1).text(link1);
23+
var link2 = "http://" + window.location.host + "/api/getProducts";
24+
$("#link2").attr("href", link2).text(link2);
25+
26+
});
27+
</script>
28+
<div class="container">
29+
<h2>Hana data in a Python web application</h2>
30+
<p>This application uses common python/web frameworks. Gathering sales informations...</p>
31+
<table id="table" class="table table-striped">
32+
<thead>
33+
<tr>
34+
<th>Region Name</th>
35+
<th>Product Name</th>
36+
<th>Sales Amount</th>
37+
</tr>
38+
</thead>
39+
<tbody></tbody>
40+
</table>
41+
<p>Try also <a id="link1"></a> or <a id="link2"></a>.</p>
42+
</div>
43+
</body>
44+
</html>

config.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class DevelopmentConfig(object):
2+
DEBUG = True
3+
TESTING = False
4+
5+
6+
class Hana(object):
7+
HOST = "localhost"
8+
PORT = "00000"
9+
USER = "SYSTEM"
10+
PASS = "XXXXXX"

requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
click==6.7
2+
Flask==0.12.2
3+
itsdangerous==0.24
4+
Jinja2==2.9.6
5+
MarkupSafe==1.0
6+
pyhdb==0.3.3
7+
Werkzeug==0.12.2

run.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from flask import Flask, render_template
2+
from app.modules.Controller import controller
3+
4+
app = Flask("HanaToPython", template_folder='app/templates', instance_relative_config=True)
5+
app.register_blueprint(controller)
6+
app.config.from_object('config.DevelopmentConfig')
7+
8+
9+
@app.route("/")
10+
def home():
11+
return render_template('index.html')
12+
13+
if __name__ == '__main__':
14+
app.run(use_reloader=True)

0 commit comments

Comments
 (0)