Skip to content

Commit fb06732

Browse files
committed
update
1 parent 8406249 commit fb06732

35 files changed

+126
-68
lines changed

Diff for: Webgenie.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,8 @@ APILOGICPROJECT_PORT=5657
3333
APILOGICSERVER_CHATGPT_APIKEY=sk-proj-
3434
3535
# Webgenie security configuration
36-
# set to false to disable authentication
37-
SECURITY_ENABLED=false
3836
# login password for the admin user
39-
ADMIN_PASSWORD=password
37+
# ADMIN_PASSWORD=password
4038
```
4139

4240

Diff for: docker-compose.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: '3.8'
2+
3+
services:
4+
webgenie:
5+
image: apilogicserver/webgenie
6+
container_name: webgenie
7+
ports:
8+
- "8080:80"
9+
networks:
10+
- als
11+
env_file:
12+
- /opt/webgenai_env
13+
stdin_open: true
14+
tty: true
15+
restart: always
16+
17+
networks:
18+
als:
19+
external: true

Diff for: sra-build/asset-manifest.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"files": {
33
"main.css": "/admin-app/static/css/main.c5a62cae.css",
4-
"main.js": "/admin-app/static/js/main.65eaf61b.js",
4+
"main.js": "/admin-app/static/js/main.be3061d8.js",
55
"static/js/2007.9dbebbd9.chunk.js": "/admin-app/static/js/2007.9dbebbd9.chunk.js",
66
"static/css/4284.dee1bf82.chunk.css": "/admin-app/static/css/4284.dee1bf82.chunk.css",
77
"static/js/4284.ba313f1f.chunk.js": "/admin-app/static/js/4284.ba313f1f.chunk.js",
@@ -93,7 +93,7 @@
9393
"static/media/codicon.ttf": "/admin-app/static/media/codicon.2fa1fcf53c57a51b064d.ttf",
9494
"index.html": "/admin-app/index.html",
9595
"main.c5a62cae.css.map": "/admin-app/static/css/main.c5a62cae.css.map",
96-
"main.65eaf61b.js.map": "/admin-app/static/js/main.65eaf61b.js.map",
96+
"main.be3061d8.js.map": "/admin-app/static/js/main.be3061d8.js.map",
9797
"2007.9dbebbd9.chunk.js.map": "/admin-app/static/js/2007.9dbebbd9.chunk.js.map",
9898
"4284.dee1bf82.chunk.css.map": "/admin-app/static/css/4284.dee1bf82.chunk.css.map",
9999
"4284.ba313f1f.chunk.js.map": "/admin-app/static/js/4284.ba313f1f.chunk.js.map",
@@ -185,6 +185,6 @@
185185
},
186186
"entrypoints": [
187187
"static/css/main.c5a62cae.css",
188-
"static/js/main.65eaf61b.js"
188+
"static/js/main.be3061d8.js"
189189
]
190190
}

Diff for: sra-build/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/admin-app/favicon.ico"/><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="ApiFabric Use AI to Generate APIs"/><link rel="apple-touch-icon" href="/admin-app/logo192.png"/><link rel="manifest" href="/admin-app/manifest.json"/><title>API Fabric - AI API Generator</title><script defer="defer" src="/admin-app/static/js/main.65eaf61b.js"></script><link href="/admin-app/static/css/main.c5a62cae.css" rel="stylesheet"></head><body><script>const origin=window.location.origin;origin.includes("apifabric")||(document.title="ApiLogicServer")</script><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/admin-app/favicon.ico"/><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="ApiFabric Use AI to Generate APIs"/><link rel="apple-touch-icon" href="/admin-app/logo192.png"/><link rel="manifest" href="/admin-app/manifest.json"/><title>API Fabric - AI API Generator</title><script defer="defer" src="/admin-app/static/js/main.be3061d8.js"></script><link href="/admin-app/static/css/main.c5a62cae.css" rel="stylesheet"></head><body><script>const origin=window.location.origin;origin.includes("apifabric")||(document.title="ApiLogicServer")</script><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Diff for: sra-build/static/js/main.00c4905d.js

-3
This file was deleted.

Diff for: sra-build/static/js/main.00c4905d.js.map

-1
This file was deleted.

Diff for: sra-build/static/js/main.1ce77fa3.js

-3
This file was deleted.

Diff for: sra-build/static/js/main.1ce77fa3.js.map

-1
This file was deleted.

Diff for: sra-build/static/js/main.2825950e.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.2825950e.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.35ef30bd.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.35ef30bd.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.65eaf61b.js

-3
This file was deleted.

Diff for: sra-build/static/js/main.65eaf61b.js.map

-1
This file was deleted.

Diff for: sra-build/static/js/main.707da02e.js

-3
This file was deleted.

Diff for: sra-build/static/js/main.707da02e.js.map

-1
This file was deleted.

Diff for: sra-build/static/js/main.b9fe496d.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.b9fe496d.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.be3061d8.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: sra-build/static/js/main.be3061d8.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: webgenai/api/customize_app.py

+12-11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import subprocess
55
import logging
66
import shutil
7+
import tempfile
8+
79
from flask import Flask, request, redirect, flash, jsonify, send_from_directory, abort
810
from werkzeug.utils import secure_filename
911
from pathlib import Path
@@ -81,20 +83,19 @@ def download_project(project_id):
8183
"""
8284
project_id = secure_filename(project_id)
8385
project = safrs.DB.session.query(Project).get(project_id)
84-
if not project:
85-
abort(404, description="Project not found")
86-
if not project.path.exists():
86+
if not project or not project.path.exists():
8787
abort(404, description="Project not found")
8888
filename = f"{project.name}.tgz"
8989
try:
90-
tar_log = subprocess.check_output(["tar", "-czf", PROJ_ROOT / filename, project.path], cwd=PROJ_ROOT)
91-
print(tar_log)
92-
shutil.move(PROJ_ROOT / filename, project.path / filename)
90+
temp_dir = Path(tempfile.mkdtemp())
91+
subprocess.check_output(["tar", "-cYYzf", filename, project.name], cwd=PROJ_ROOT, stderr=subprocess.STDOUT, universal_newlines=True)
92+
shutil.move(PROJ_ROOT / filename, temp_dir / filename)
9393
except subprocess.CalledProcessError as e:
94-
log.error(f"Project tar error: {e}")
95-
abort(404, description="Project tar error")
94+
log.error(f"download_project tar error: {e} - {e.output}")
95+
abort(500, description="Project tar error")
9696
except Exception as e:
97-
log.error(f"Project tar error: {e}")
98-
abort(404, description="Project tar error")
99-
return send_from_directory(project.path, filename, as_attachment=True)
97+
log.error(f"download_project tar error: {e}")
98+
abort(500, description="Project tar error")
99+
100+
return send_from_directory(temp_dir, filename, as_attachment=True)
100101

Diff for: webgenai/arun.sh

+10
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@ export UPLOAD_FOLDER="${PROJ_ROOT}/wgupload"
1313
mkdir -p "${UPLOAD_FOLDER}" "${PROJ_ROOT}/wgadmin/nginx"
1414

1515
RED='\033[0;31m'
16+
GREEN='\033[0;32m'
1617
NC='\033[0m' # No Color
1718

1819
nginx -g 'daemon off;' &
1920
echo "Nginx started"
2021

22+
# Enable security if password is set in container environment
23+
[[ -n "${ADMIN_PASSWORD}" ]] && export SECURITY_ENABLED="true"
24+
2125
if [[ -z ${SECURITY_ENABLED} || ${SECURITY_ENABLED} == "false" || ${SECURITY_ENABLED} == "no" ]] ; then
2226
echo -e "${RED}Authentication disabled (\$SECURITY_ENABLED=${SECURITY_ENABLED}) ${NC}"
27+
else
28+
echo -e "${GREEN}Authentication enabled ${NC}"
29+
export JWT_SECRET_KEY=${JWT_SECRET_KEY:-$(openssl rand -hex 32)}
2330
fi
2431

2532
if [[ -z ${APILOGICSERVER_CHATGPT_APIKEY} ]]; then
@@ -41,5 +48,8 @@ fi
4148
# Kill any running project / set "running" to false
4249
python database/manager.py -K
4350

51+
# Temp fix
52+
> /home/api_logic_server/api_logic_server_cli/templates/opt_locking.txt
53+
4454
export GUNICORN_CMD_ARGS=" --worker-tmp-dir=/dev/shm -b 0.0.0.0:${APILOGICPROJECT_PORT} --timeout 60 --workers 3 --threads 2 --reload"
4555
gunicorn api_logic_server_run:flask_app

Diff for: webgenai/database/db.sqlite

0 Bytes
Binary file not shown.

Diff for: webgenai/database/models/__init__.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
Base = declarative_base() # type: flask_sqlalchemy.model.DefaultMeta
3131
metadata = Base.metadata
3232

33-
APP_ORIGIN = "http://localhost:{port}"
34-
APP_ADMIN_ORIGIN = "http://localhost:5657"
35-
ADMIN_UID = "5d9ada40-5d62-11ef-966d-eb8351752909"
33+
3634
PROJ_ROOT = Path(os.getenv("PROJ_ROOT","/opt/projects"))
3735
FIRST_PORT = 6000
3836
UPLOAD_ROOT = f"{PROJ_ROOT}/wgupload"

Diff for: webgenai/database/models/ai_api_requests/default.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
{
99
"role": "user",
10-
"content": "Use SQLAlchemy to create a sqlite database named system/genai/temp/model.sqlite .\n\nThe purpose of the database is: {INPUT}\n\nCreate at least {COMPLEXITY} tables.\n\nHints: use autonum keys, allow nulls, foreign keys, no check constraints.\nIf you choose to use a date, only use python datetime datatype.\nRemember that SQLite DateTime type only accepts Python datetime and date objects as input, this means you can not enter string attributes where a date or datetime object is expected.Provide a short description of each table. Include the description in each data model class docstring, prefixed with 'description: '. \nDon't use python DECIMAL type.\nDon't install additional packages.\nDon't use the faker pip package.\n\nCreate at least {DATA_COMPLEXITY} rows of sample data, use foreign key columns instead of relationship names for the data inserts."
10+
"content": "Use SQLAlchemy to create a sqlite database named system/genai/temp/model.sqlite .\n\nThe purpose of the database is: {INPUT}\n\nCreate at least {COMPLEXITY} tables.\n\nHints: use autonum keys, allow nulls, foreign keys, no check constraints.\nIf you choose to use a date, only use python datetime datatype.\nRemember that SQLite DateTime type only accepts Python datetime and date objects as input, this means you can not enter string attributes where a date or datetime object is expected.Provide a short description of each table. Include the description in each data model class docstring, prefixed with 'description: '. \nDon't use python DECIMAL type.\nDon't install additional packages.\nDon't use the faker pip package.\n\nCreate at least {DATA_COMPLEXITY} rows of sample data, use foreign key columns instead of relationship names for the data inserts. Add at least one row per table."
1111
}
1212
]
1313
}

Diff for: webgenai/database/models/project.py

+47-24
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from sqlalchemy.dialects.sqlite import *
2828
from .util.xls2sql import create_sqlite
2929
from .util import kill_processes_by_port
30-
from . import BaseModel, apifab_dec, FIRST_PORT, PROJ_ROOT, APP_ORIGIN, APP_ADMIN_ORIGIN, secure_filename_webgenai, log
30+
from . import BaseModel, apifab_dec, FIRST_PORT, PROJ_ROOT, secure_filename_webgenai, log
3131

3232
# Scripts to manage projects (create, start, etc)
3333
CREATE_WGAI_SCRIPT = Path(__file__).parent / "util" / "create_wgai_project.sh"
@@ -103,8 +103,6 @@ def __init__(self, *args, **kwargs):
103103
self.configure_nginx()
104104

105105
kwargs['pid'] = proj_process.pid
106-
kwargs['download'] = f'{APP_ADMIN_ORIGIN}/download_project/{self.id}'
107-
kwargs['response'] = f'{APP_ADMIN_ORIGIN}/projects/{self.id}/system/genai/temp/chatgpt_retry.response'
108106
kwargs['created_at'] = datetime.datetime.now()
109107

110108
return BaseModel.__init__(self, *args, **kwargs)
@@ -196,16 +194,19 @@ def test_conn(cls, *args, **kwargs):
196194
Method to test a database connection string
197195
"""
198196
log.debug(f"Testing connection: {kwargs.get('connection_string')}")
199-
try:
200-
engine = create_engine(kwargs.get("connection_string"))
201-
with engine.connect() as connection:
202-
result = connection.execute(text("SELECT 1"))
203-
result.fetchone()
204-
result = { "msg" : "Connection successful!", "success": True}
205-
except Exception as e:
206-
log.warning(f"Connection failed: {e}")
207-
log.exception(e)
208-
result = { "msg" : f"Connection failed: {e}", "success": False}
197+
connection_string = kwargs.get("connection_string")
198+
result = { "msg" : f"Invalid connection string", "success": False}
199+
if connection_string and not connection_string.endswith("/"):
200+
try:
201+
engine = create_engine(connection_string)
202+
with engine.connect() as connection:
203+
result = connection.execute(text("SELECT 1"))
204+
result.fetchone()
205+
result = { "msg" : "Connection successful!", "success": True}
206+
except Exception as e:
207+
log.warning(f"Connection failed: {e}")
208+
log.exception(e)
209+
result = { "msg" : f"Connection failed: {e}", "success": False}
209210

210211
return result
211212

@@ -251,13 +252,20 @@ def env(self):
251252
Method to return the environment variables for the project
252253
"""
253254
env = os.environ.copy()
254-
if 'SQLALCHEMY_DATABASE_URI' in env:
255-
del env['SQLALCHEMY_DATABASE_URI']
256-
return env | {
257-
"APILOGICPROJECT_SWAGGER_PORT": "8080", #str(self.port),
255+
# there are secrets in the env, don't just pass it
256+
return {
257+
"APILOGICPROJECT_SWAGGER_PORT": env.get("APILOGICPROJECT_SWAGGER_PORT", "8080"),
258+
"APILOGICPROJECT_EXTERNAL_PORT": env.get("APILOGICPROJECT_EXTERNAL_PORT", "8080"),
259+
"APILOGICPROJECT_EXTERNAL_HOST": env.get("APILOGICPROJECT_EXTERNAL_HOST", "localhost"),
260+
"APILOGICPROJECT_SWAGGER_HOST": env.get("APILOGICPROJECT_SWAGGER_HOST", "localhost"),
261+
"WG_SQLALCHEMY_DATABASE_URI": env.get("WG_SQLALCHEMY_DATABASE_URI", "sqlite:////opt/webgenai/database/db.sqlite"),
262+
"APILOGICSERVER_CHATGPT_APIKEY" : env.get("APILOGICSERVER_CHATGPT_APIKEY",""),
263+
"PROJ_ROOT": str(PROJ_ROOT),
264+
"PATH": env.get("PATH"),
258265
"APILOGICPROJECT_PORT": str(self.port),
259266
"SECURITY_ENABLED": "false",
260-
"APILOGICPROJECT_API_PREFIX": f"/{self.id}"
267+
"APILOGICPROJECT_API_PREFIX": f"/{self.id}",
268+
261269
}
262270

263271
@jsonapi_attr
@@ -312,15 +320,30 @@ def get_log(self, *args, **kwargs):
312320

313321
return self
314322

323+
@property
324+
def app_origin(self):
325+
return
326+
315327
@jsonapi_attr
316328
def link(self):
317-
#return f'{APP_ORIGIN}/admin-app/index.html#/Configuration'.format(port = self.port)
318-
#return f"{APP_ADMIN_ORIGIN}/admin-app/index.html#/Configuration?load={APP_ADMIN_ORIGIN}/{self.id}/admin.yaml"
319-
#return f"/admin-app/index.html#/Configuration?load={app_admin_origin}/{self.id}/admin.yaml"
320-
app_admin_origin = "http://localhost:8080"
321-
#return f"{app_admin_origin}/admin-app/index.html#/Configuration?load={app_admin_origin}/{self.id}/admin.yaml"
322-
return f"{app_admin_origin}/{self.id}/admin-app/index.html"
329+
"""
323330
331+
"""
332+
return f"/{self.id}/admin-app/index.html"
333+
334+
@jsonapi_attr
335+
def download(self):
336+
"""
337+
338+
"""
339+
return f"/download_project/{self.id}"
340+
341+
@jsonapi_attr
342+
def response(self):
343+
"""
344+
345+
"""
346+
return f"/download_project/{self.id}"
324347

325348
@property
326349
def path(self):

Diff for: webgenai/database/models/util/create_db_project.sh

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function log() {
5151
fi
5252
}
5353

54+
env > /tmp/env.txt
5455
#command = [CREATE_DB_SCRIPT, name, kwargs['id'], connnection_string, str(kwargs['port'])]
5556
proj_name=$1
5657
proj_id=$2

Diff for: webgenai/grun.sh

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export APILOGICPROJECT_API_PREFIX="${APILOGICPROJECT_API_PREFIX}"
99

1010
python api_logic_server_run.py
1111
exit
12+
13+
1214
export GUNICORN_CMD_ARGS=" --worker-tmp-dir=/dev/shm --log-level=debug -b 0.0.0.0:${APILOGICPROJECT_PORT} --timeout 60 -w3 -t3 --reload"
1315
gunicorn api_logic_server_run:flask_app
1416

Diff for: webgenai/security/authentication_provider/custom/auth_provider.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ def configure_auth(flask_app):
4343
"""
4444
Called by authentication.py on server start to initialize JWT_SECRET_KEY
4545
"""
46-
flask_app.config["JWT_SECRET_KEY"] = os.getenv("JWT_SECRET_KEY", str(uuid.uuid4()))
46+
jwt_secret_key = os.getenv("JWT_SECRET_KEY")
47+
if not jwt_secret_key:
48+
jwt_secret_key = str(uuid.uuid4())
49+
os.environ["JWT_SECRET_KEY"] = jwt_secret_key
50+
flask_app.config["JWT_SECRET_KEY"] = jwt_secret_key
4751
flask_app.config['JWT_TOKEN_LOCATION'] = ['headers', 'cookies']
4852

4953
@classmethod

Diff for: webgenai/security/system/authentication.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def login():
2525
from flask import jsonify, request
2626
from flask_jwt_extended import JWTManager
2727
from flask_jwt_extended import jwt_required as jwt_required_ori
28-
from flask_jwt_extended import create_access_token
28+
from flask_jwt_extended import create_access_token, create_refresh_token, set_access_cookies, set_refresh_cookies
2929
from datetime import timedelta
3030
from functools import wraps
3131
import config.config as config
@@ -64,8 +64,6 @@ def configure_auth(flask_app: Flask, database: object, method_decorators: list[o
6464
_type_: (no return)
6565
"""
6666
from config.config import Config
67-
68-
6967

7068
flask_app.config["PROPAGATE_EXCEPTIONS"] = True
7169
flask_app.config["JWT_SECRET_KEY"] = flask_app.config.get("JWT_SECRET_KEY", "ApiLogicServerSecret") # Change this!
@@ -111,9 +109,13 @@ def login():
111109
return jsonify("Wrong username or password"), 401
112110

113111
access_token = create_access_token(identity=user) # serialize and encode
112+
refresh_token = create_refresh_token(identity=user)
114113
from flask import g
115114
g.access_token = access_token
116-
return jsonify(access_token=access_token)
115+
response = jsonify(access_token=access_token)
116+
set_access_cookies(response, access_token)
117+
set_refresh_cookies(response, refresh_token)
118+
return response
117119

118120
@jwt.user_identity_loader
119121
def user_identity_lookup(user):

Diff for: webgenai/ui/admin/admin.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ resources:
113113
resource: Project
114114
type: User
115115
user_key: username
116-
conf_source: aHR0cHM6Ly9hcGlmYWJyaWMuYWkvYWRtaW4ueWFtbA==
116+
117117
ui:
118118
theme:
119119
name: default

0 commit comments

Comments
 (0)