Skip to content

Commit 925db1b

Browse files
Merge pull request #50 from Geode-solutions/feat/blueprint_routes
Feat/blueprint_routes
2 parents 945e092 + 51c765e commit 925db1b

17 files changed

+519
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ venv
44
output
55
__pycache__
66
.vscode
7+
uploads

app.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
""" Packages """
2+
import os
3+
4+
import flask
5+
import flask_cors
6+
from werkzeug.exceptions import HTTPException
7+
8+
from werkzeug.exceptions import HTTPException
9+
10+
from src.opengeodeweb_back.routes import blueprint_routes
11+
12+
13+
""" Global config """
14+
app = flask.Flask(__name__)
15+
16+
""" Config variables """
17+
FLASK_DEBUG = True if os.environ.get("FLASK_DEBUG", default=None) == "True" else False
18+
19+
if FLASK_DEBUG == False:
20+
app.config.from_object("config.ProdConfig")
21+
else:
22+
app.config.from_object("config.DevConfig")
23+
24+
25+
PORT = int(app.config.get("PORT"))
26+
ORIGINS = app.config.get("ORIGINS")
27+
SSL = app.config.get("SSL")
28+
29+
flask_cors.CORS(app, origins=ORIGINS)
30+
app.register_blueprint(
31+
blueprint_routes.routes,
32+
url_prefix="/",
33+
name="blueprint_routes",
34+
)
35+
36+
37+
@app.errorhandler(HTTPException)
38+
def handle_exception(e):
39+
response = e.get_response()
40+
response.data = flask.json.dumps(
41+
{
42+
"code": e.code,
43+
"name": e.name,
44+
"description": e.description,
45+
}
46+
)
47+
response.content_type = "application/json"
48+
return response
49+
50+
51+
# ''' Main '''
52+
if __name__ == "__main__":
53+
print(f"Python is running in {FLASK_DEBUG} mode")
54+
app.run(debug=FLASK_DEBUG, host="0.0.0.0", port=PORT, ssl_context=SSL)

config.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
""" Flask configuration """
2+
import os
3+
4+
5+
class Config(object):
6+
FLASK_DEBUG = os.environ.get("FLASK_DEBUG", default=False)
7+
ID = os.environ.get("ID", default=None)
8+
PORT = "5000"
9+
CORS_HEADERS = "Content-Type"
10+
UPLOAD_FOLDER = "./uploads"
11+
WORKFLOWS_DATA_FOLDER = "./data_workflows/"
12+
LOCK_FOLDER = "./lock/"
13+
TIME_FOLDER = "./time/"
14+
15+
16+
class ProdConfig(Config):
17+
SSL = None
18+
ORIGINS = ["*"]
19+
MINUTES_BEFORE_TIMEOUT = "5"
20+
SECONDS_BETWEEN_SHUTDOWNS = "150"
21+
DATA_FOLDER = "/data/"
22+
23+
24+
class DevConfig(Config):
25+
SSL = None
26+
ORIGINS = "http://localhost:3000"
27+
MINUTES_BEFORE_TIMEOUT = "1000"
28+
SECONDS_BETWEEN_SHUTDOWNS = "60"
29+
DATA_FOLDER = "./data/"

requirements.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ geode-explicit
1010
geode-implicit
1111
geode-common
1212
jsonschema
13-
flask[async]
13+
Flask[async]
14+
Flask-Cors
1415
werkzeug

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ click==8.1.7
1717
colorama==0.4.6
1818
# via click
1919
flask[async]==3.0.0
20+
# via
21+
# -r requirements.in
22+
# flask-cors
23+
flask-cors==4.0.0
2024
# via -r requirements.in
2125
geode-background==7.4.9
2226
# via

src/opengeodeweb_back/geode_functions.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
# Standard library imports
2-
import base64
32
import os
43
import time
54
import threading
65
import uuid
6+
import zipfile
77

88
# Third party imports
99
import flask
1010
import opengeode_geosciences as og_gs
1111
import opengeode as og
1212
import pkg_resources
13-
import werkzeug
1413
from jsonschema import validate
1514
from jsonschema.exceptions import ValidationError
1615

@@ -311,7 +310,7 @@ def send_file(upload_folder, saved_files, new_file_name):
311310
mimetype = "application/octet-binary"
312311
else:
313312
mimetype = "application/zip"
314-
new_file_name = strict_file_name + ".zip"
313+
new_file_name = os.path.splitext(new_file_name)[0] + ".zip"
315314
with zipfile.ZipFile(os.path.join(upload_folder, new_file_name), "w") as zipObj:
316315
for saved_file_path in saved_files:
317316
zipObj.write(
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Standard library imports
2+
import json
3+
import os
4+
5+
# Third party imports
6+
import flask
7+
import flask_cors
8+
from .. import geode_functions
9+
import werkzeug
10+
11+
12+
routes = flask.Blueprint("routes", __name__)
13+
flask_cors.CORS(routes)
14+
15+
16+
schemas = os.path.join(os.path.dirname(__file__), "schemas")
17+
18+
with open(
19+
os.path.join(schemas, "allowed_files.json"),
20+
"r",
21+
) as file:
22+
allowed_files_json = json.load(file)
23+
24+
25+
@routes.route(
26+
allowed_files_json["route"],
27+
methods=allowed_files_json["methods"],
28+
)
29+
def allowed_files():
30+
geode_functions.validate_request(flask.request, allowed_files_json)
31+
extensions = geode_functions.list_input_extensions(flask.request.json["key"])
32+
return {"status": 200, "extensions": extensions}
33+
34+
35+
with open(
36+
os.path.join(schemas, "upload_file.json"),
37+
"r",
38+
) as file:
39+
upload_file_json = json.load(file)
40+
41+
42+
@routes.route(
43+
upload_file_json["route"],
44+
methods=upload_file_json["methods"],
45+
)
46+
def upload_file():
47+
if flask.request.method == "OPTIONS":
48+
return flask.make_response({}, 200)
49+
50+
UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
51+
if not os.path.exists(UPLOAD_FOLDER):
52+
os.mkdir(UPLOAD_FOLDER)
53+
file = flask.request.files["file"]
54+
filename = werkzeug.utils.secure_filename(os.path.basename(file.filename))
55+
file.save(os.path.join(UPLOAD_FOLDER, filename))
56+
return flask.make_response({"message": "File uploaded"}, 201)
57+
58+
59+
with open(
60+
os.path.join(schemas, "allowed_objects.json"),
61+
"r",
62+
) as file:
63+
allowed_objects_json = json.load(file)
64+
65+
66+
@routes.route(
67+
allowed_objects_json["route"],
68+
methods=allowed_objects_json["methods"],
69+
)
70+
def allowed_objects():
71+
if flask.request.method == "OPTIONS":
72+
return flask.make_response({}, 200)
73+
74+
UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
75+
geode_functions.validate_request(flask.request, allowed_objects_json)
76+
file_absolute_path = os.path.join(UPLOAD_FOLDER, flask.request.json["filename"])
77+
allowed_objects = geode_functions.list_geode_objects(
78+
file_absolute_path, flask.request.json["key"]
79+
)
80+
return flask.make_response({"allowed_objects": allowed_objects}, 200)
81+
82+
83+
with open(
84+
os.path.join(schemas, "missing_files.json"),
85+
"r",
86+
) as file:
87+
missing_files_json = json.load(file)
88+
89+
90+
@routes.route(
91+
missing_files_json["route"],
92+
methods=missing_files_json["methods"],
93+
)
94+
def missing_files():
95+
UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
96+
geode_functions.validate_request(flask.request, missing_files_json)
97+
98+
missing_files = geode_functions.missing_files(
99+
flask.request.json["input_geode_object"],
100+
os.path.join(UPLOAD_FOLDER, flask.request.json["filename"]),
101+
)
102+
has_missing_files = missing_files.has_missing_files()
103+
104+
mandatory_files = []
105+
for mandatory_file in missing_files.mandatory_files:
106+
mandatory_files.append(os.path.basename(mandatory_file))
107+
108+
additional_files = []
109+
for additional_file in missing_files.additional_files:
110+
additional_files.append(os.path.basename(additional_file))
111+
112+
return flask.make_response(
113+
{
114+
"has_missing_files": has_missing_files,
115+
"mandatory_files": mandatory_files,
116+
"additional_files": additional_files,
117+
},
118+
200,
119+
)
120+
121+
122+
with open(
123+
os.path.join(schemas, "geographic_coordinate_systems.json"),
124+
"r",
125+
) as file:
126+
geographic_coordinate_systems_json = json.load(file)
127+
128+
129+
@routes.route(
130+
geographic_coordinate_systems_json["route"],
131+
methods=geographic_coordinate_systems_json["methods"],
132+
)
133+
def crs_converter_geographic_coordinate_systems():
134+
geode_functions.validate_request(flask.request, geographic_coordinate_systems_json)
135+
infos = geode_functions.geographic_coordinate_systems(
136+
flask.request.json["input_geode_object"]
137+
)
138+
crs_list = []
139+
140+
for info in infos:
141+
crs = {}
142+
crs["name"] = info.name
143+
crs["code"] = info.code
144+
crs["authority"] = info.authority
145+
crs_list.append(crs)
146+
147+
return flask.make_response({"crs_list": crs_list}, 200)
148+
149+
150+
with open(
151+
os.path.join(schemas, "geode_objects_and_output_extensions.json"),
152+
"r",
153+
) as file:
154+
geode_objects_and_output_extensions_json = json.load(file)
155+
156+
157+
@routes.route(
158+
geode_objects_and_output_extensions_json["route"],
159+
methods=geode_objects_and_output_extensions_json["methods"],
160+
)
161+
def geode_objects_and_output_extensions():
162+
UPLOAD_FOLDER = flask.current_app.config["UPLOAD_FOLDER"]
163+
geode_functions.validate_request(
164+
flask.request, geode_objects_and_output_extensions_json
165+
)
166+
data = geode_functions.load(
167+
flask.request.json["input_geode_object"],
168+
os.path.join(UPLOAD_FOLDER, flask.request.json["filename"]),
169+
)
170+
geode_objects_and_output_extensions = (
171+
geode_functions.geode_objects_output_extensions(
172+
flask.request.json["input_geode_object"], data
173+
)
174+
)
175+
return flask.make_response(
176+
{"geode_objects_and_output_extensions": geode_objects_and_output_extensions},
177+
200,
178+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"$id": "/allowed_files",
3+
"route": "/allowed_files",
4+
"methods": [
5+
"POST"
6+
],
7+
"type": "object",
8+
"properties": {
9+
"key": {
10+
"type": [
11+
"string",
12+
"null"
13+
]
14+
}
15+
},
16+
"required": [
17+
"key"
18+
],
19+
"additionalProperties": false
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"$id": "/tools/allowed_objects",
3+
"route": "/allowed_objects",
4+
"methods": ["POST"],
5+
"type": "object",
6+
"properties": {
7+
"filename": {
8+
"type": "string"
9+
},
10+
"key": {
11+
"type": ["string", "null"]
12+
}
13+
},
14+
"required": ["filename", "key"],
15+
"additionalProperties": false
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$id": "/tools/geode_objects_and_output_extensions",
3+
"route": "/geode_objects_and_output_extensions",
4+
"methods": [
5+
"POST"
6+
],
7+
"type": "object",
8+
"properties": {
9+
"input_geode_object": {
10+
"type": "string"
11+
},
12+
"filename": {
13+
"type": "string"
14+
}
15+
},
16+
"required": [
17+
"input_geode_object",
18+
"filename"
19+
],
20+
"additionalProperties": false
21+
}

0 commit comments

Comments
 (0)