ivoryos 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ivoryos might be problematic. Click here for more details.

Files changed (37) hide show
  1. ivoryos/__init__.py +118 -99
  2. ivoryos/config.py +47 -47
  3. ivoryos/routes/auth/auth.py +100 -65
  4. ivoryos/routes/auth/templates/auth/login.html +25 -25
  5. ivoryos/routes/auth/templates/auth/signup.html +32 -32
  6. ivoryos/routes/control/control.py +400 -272
  7. ivoryos/routes/control/templates/control/controllers.html +75 -75
  8. ivoryos/routes/control/templates/control/controllers_home.html +50 -50
  9. ivoryos/routes/control/templates/control/controllers_new.html +89 -89
  10. ivoryos/routes/database/database.py +188 -114
  11. ivoryos/routes/database/templates/database/experiment_database.html +72 -72
  12. ivoryos/routes/design/design.py +542 -406
  13. ivoryos/routes/design/templates/design/experiment_builder.html +415 -412
  14. ivoryos/routes/design/templates/design/experiment_run.html +325 -325
  15. ivoryos/routes/main/main.py +42 -25
  16. ivoryos/routes/main/templates/main/help.html +141 -141
  17. ivoryos/routes/main/templates/main/home.html +68 -68
  18. ivoryos/static/.DS_Store +0 -0
  19. ivoryos/static/js/overlay.js +12 -12
  20. ivoryos/static/js/socket_handler.js +34 -34
  21. ivoryos/static/js/sortable_card.js +24 -24
  22. ivoryos/static/js/sortable_design.js +36 -36
  23. ivoryos/static/style.css +201 -201
  24. ivoryos/templates/base.html +143 -143
  25. ivoryos/utils/db_models.py +518 -500
  26. ivoryos/utils/form.py +316 -316
  27. ivoryos/utils/global_config.py +67 -67
  28. ivoryos/utils/llm_agent.py +183 -183
  29. ivoryos/utils/script_runner.py +165 -164
  30. ivoryos/utils/utils.py +425 -422
  31. ivoryos/version.py +1 -0
  32. {ivoryos-0.1.8.dist-info → ivoryos-0.1.10.dist-info}/LICENSE +21 -21
  33. {ivoryos-0.1.8.dist-info → ivoryos-0.1.10.dist-info}/METADATA +170 -166
  34. ivoryos-0.1.10.dist-info/RECORD +47 -0
  35. {ivoryos-0.1.8.dist-info → ivoryos-0.1.10.dist-info}/WHEEL +1 -1
  36. ivoryos-0.1.8.dist-info/RECORD +0 -45
  37. {ivoryos-0.1.8.dist-info → ivoryos-0.1.10.dist-info}/top_level.txt +0 -0
ivoryos/__init__.py CHANGED
@@ -1,99 +1,118 @@
1
- import os
2
- import sys
3
- from typing import Union
4
-
5
- from flask import Flask, redirect, url_for
6
-
7
- from ivoryos.config import Config, get_config
8
- from ivoryos.routes.auth.auth import auth, login_manager
9
- from ivoryos.routes.control.control import control
10
- from ivoryos.routes.database.database import database
11
- from ivoryos.routes.design.design import design, socketio
12
- from ivoryos.routes.main.main import main
13
- from ivoryos.utils import utils
14
- from ivoryos.utils.db_models import db
15
- from ivoryos.utils.global_config import GlobalConfig
16
- from ivoryos.utils.script_runner import ScriptRunner
17
-
18
- global_config = GlobalConfig()
19
-
20
-
21
- def create_app(config_class=None):
22
- url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
23
- app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
24
- app.config.from_object(config_class or 'config.get_config()')
25
-
26
- # Initialize extensions
27
- socketio.init_app(app)
28
- login_manager.init_app(app)
29
- login_manager.login_view = "auth.login"
30
- db.init_app(app)
31
-
32
- # Create database tables
33
- with app.app_context():
34
- db.create_all()
35
-
36
- # Additional setup
37
- utils.create_gui_dir(app.config['OUTPUT_FOLDER'])
38
-
39
- # logger_list = app.config["LOGGERS"]
40
- logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
41
- logger = utils.start_logger(socketio, 'gui_logger', logger_path)
42
-
43
- @app.before_request
44
- def before_request():
45
- from flask import g
46
- g.logger = logger
47
- g.socketio = socketio
48
-
49
- app.register_blueprint(main, url_prefix=url_prefix)
50
- app.register_blueprint(auth, url_prefix=url_prefix)
51
- app.register_blueprint(design, url_prefix=url_prefix)
52
- app.register_blueprint(database, url_prefix=url_prefix)
53
- app.register_blueprint(control, url_prefix=url_prefix)
54
-
55
- @app.route('/')
56
- def redirect_to_prefix():
57
- return redirect(url_for('main.index')) # Assuming 'index' is a route in your blueprint
58
-
59
- return app
60
-
61
-
62
- def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, model=None,
63
- config: Config = None,
64
- logger: Union[str, list] = None,
65
- logger_output_name: str = None,
66
- ):
67
- app = create_app(config_class=config or get_config()) # Create app instance using factory function
68
-
69
- port = port or int(os.environ.get("PORT", 8000))
70
- debug = debug if debug is not None else app.config.get('DEBUG', True)
71
-
72
- app.config["LOGGERS"] = logger
73
- app.config["LOGGERS_PATH"] = logger_output_name or app.config["LOGGERS_PATH"] # default.log
74
- logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
75
-
76
- if module:
77
- app.config["MODULE"] = module
78
- app.config["OFF_LINE"] = False
79
- global_config.deck = sys.modules[module]
80
- global_config.deck_snapshot = utils.create_deck_snapshot(global_config.deck, output_path=app.config["DUMMY_DECK"], save=True)
81
- # global_config.runner = ScriptRunner(globals())
82
- else:
83
- app.config["OFF_LINE"] = True
84
- if model:
85
- app.config["ENABLE_LLM"] = True
86
- app.config["LLM_MODEL"] = model
87
- app.config["LLM_SERVER"] = llm_server
88
- utils.install_and_import('openai')
89
- from ivoryos.utils.llm_agent import LlmAgent
90
- global_config.agent = LlmAgent(host=llm_server, model=model,
91
- output_path=app.config["OUTPUT_FOLDER"] if module is not None else None)
92
- else:
93
- app.config["ENABLE_LLM"] = False
94
- if logger and type(logger) is str:
95
- utils.start_logger(socketio, log_filename=logger_path, logger_name=logger)
96
- elif type(logger) is list:
97
- for log in logger:
98
- utils.start_logger(socketio, log_filename=logger_path, logger_name=log)
99
- socketio.run(app, host=host, port=port, debug=debug, use_reloader=False, allow_unsafe_werkzeug=True)
1
+ import os
2
+ import sys
3
+ from typing import Union
4
+
5
+ from flask import Flask, redirect, url_for
6
+
7
+ from ivoryos.config import Config, get_config
8
+ from ivoryos.routes.auth.auth import auth, login_manager
9
+ from ivoryos.routes.control.control import control
10
+ from ivoryos.routes.database.database import database
11
+ from ivoryos.routes.design.design import design, socketio
12
+ from ivoryos.routes.main.main import main
13
+ from ivoryos.utils import utils
14
+ from ivoryos.utils.db_models import db
15
+ from ivoryos.utils.global_config import GlobalConfig
16
+ from ivoryos.utils.script_runner import ScriptRunner
17
+ from ivoryos.version import __version__ as ivoryos_version
18
+
19
+ global_config = GlobalConfig()
20
+
21
+
22
+ url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
23
+ app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
24
+ app.register_blueprint(main, url_prefix=url_prefix)
25
+ app.register_blueprint(auth, url_prefix=url_prefix)
26
+ app.register_blueprint(design, url_prefix=url_prefix)
27
+ app.register_blueprint(database, url_prefix=url_prefix)
28
+ app.register_blueprint(control, url_prefix=url_prefix)
29
+
30
+ def create_app(config_class=None):
31
+ # url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
32
+ # app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
33
+ app.config.from_object(config_class or 'config.get_config()')
34
+
35
+ # Initialize extensions
36
+ socketio.init_app(app)
37
+ login_manager.init_app(app)
38
+ login_manager.login_view = "auth.login"
39
+ db.init_app(app)
40
+
41
+ # Create database tables
42
+ with app.app_context():
43
+ db.create_all()
44
+
45
+ # Additional setup
46
+ utils.create_gui_dir(app.config['OUTPUT_FOLDER'])
47
+
48
+ # logger_list = app.config["LOGGERS"]
49
+ logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
50
+ logger = utils.start_logger(socketio, 'gui_logger', logger_path)
51
+
52
+ @app.before_request
53
+ def before_request():
54
+ from flask import g
55
+ g.logger = logger
56
+ g.socketio = socketio
57
+
58
+
59
+
60
+ @app.route('/')
61
+ def redirect_to_prefix():
62
+ return redirect(url_for('main.index', version=ivoryos_version)) # Assuming 'index' is a route in your blueprint
63
+
64
+ return app
65
+
66
+
67
+ def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, model=None,
68
+ config: Config = None,
69
+ logger: Union[str, list] = None,
70
+ logger_output_name: str = None,
71
+ ):
72
+ """
73
+ Start ivoryOS app server.
74
+
75
+ :param module: module name, __name__ for current module
76
+ :param host: host address, defaults to 0.0.0.0
77
+ :param port: port, defaults to None, and will use 8000
78
+ :param debug: debug mode, defaults to None (True)
79
+ :param llm_server: llm server, defaults to None.
80
+ :param model: llm model, defaults to None. If None, app will run without text-to-code feature
81
+ :param config: config class, defaults to None
82
+ :param logger: logger name of list of logger names, defaults to None
83
+ :param logger_output_name: log file save name of logger, defaults to None, and will use "default.log"
84
+
85
+ """
86
+ app = create_app(config_class=config or get_config()) # Create app instance using factory function
87
+
88
+ port = port or int(os.environ.get("PORT", 8000))
89
+ debug = debug if debug is not None else app.config.get('DEBUG', True)
90
+
91
+ app.config["LOGGERS"] = logger
92
+ app.config["LOGGERS_PATH"] = logger_output_name or app.config["LOGGERS_PATH"] # default.log
93
+ logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
94
+
95
+ if module:
96
+ app.config["MODULE"] = module
97
+ app.config["OFF_LINE"] = False
98
+ global_config.deck = sys.modules[module]
99
+ global_config.deck_snapshot = utils.create_deck_snapshot(global_config.deck, output_path=app.config["DUMMY_DECK"], save=True)
100
+ # global_config.runner = ScriptRunner(globals())
101
+ else:
102
+ app.config["OFF_LINE"] = True
103
+ if model:
104
+ app.config["ENABLE_LLM"] = True
105
+ app.config["LLM_MODEL"] = model
106
+ app.config["LLM_SERVER"] = llm_server
107
+ utils.install_and_import('openai')
108
+ from ivoryos.utils.llm_agent import LlmAgent
109
+ global_config.agent = LlmAgent(host=llm_server, model=model,
110
+ output_path=app.config["OUTPUT_FOLDER"] if module is not None else None)
111
+ else:
112
+ app.config["ENABLE_LLM"] = False
113
+ if logger and type(logger) is str:
114
+ utils.start_logger(socketio, log_filename=logger_path, logger_name=logger)
115
+ elif type(logger) is list:
116
+ for log in logger:
117
+ utils.start_logger(socketio, log_filename=logger_path, logger_name=log)
118
+ socketio.run(app, host=host, port=port, debug=debug, use_reloader=False, allow_unsafe_werkzeug=True)
ivoryos/config.py CHANGED
@@ -1,47 +1,47 @@
1
- import os
2
- from dotenv import load_dotenv
3
-
4
- # Load environment variables from .env file
5
- load_dotenv()
6
-
7
-
8
- class Config:
9
- SECRET_KEY = os.getenv('SECRET_KEY', 'default_secret_key')
10
- OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', None)
11
-
12
- OUTPUT_FOLDER = os.path.join(os.path.abspath(os.curdir), 'ivoryos_data')
13
- os.makedirs(OUTPUT_FOLDER, exist_ok=True)
14
- CSV_FOLDER = os.path.join(OUTPUT_FOLDER, 'config_csv/')
15
- SCRIPT_FOLDER = os.path.join(OUTPUT_FOLDER, 'scripts/')
16
- DATA_FOLDER = os.path.join(OUTPUT_FOLDER, 'results/')
17
- DUMMY_DECK = os.path.join(OUTPUT_FOLDER, 'pseudo_deck/')
18
- LLM_OUTPUT = os.path.join(OUTPUT_FOLDER, 'llm_output/')
19
- DECK_HISTORY = os.path.join(OUTPUT_FOLDER, 'deck_history.txt')
20
- LOGGERS_PATH = "default.log"
21
-
22
- SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(OUTPUT_FOLDER, 'ivoryos.db')}"
23
- SQLALCHEMY_TRACK_MODIFICATIONS = False
24
-
25
- ENABLE_LLM = True if OPENAI_API_KEY else False
26
- OFF_LINE = True
27
-
28
-
29
- class DevelopmentConfig(Config):
30
- DEBUG = True
31
-
32
-
33
- class ProductionConfig(Config):
34
- DEBUG = False
35
-
36
-
37
- class TestingConfig(Config):
38
- DEBUG = True
39
- TESTING = True
40
-
41
-
42
- def get_config(env='dev'):
43
- if env == 'production':
44
- return ProductionConfig()
45
- elif env == 'testing':
46
- return TestingConfig()
47
- return DevelopmentConfig()
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ # Load environment variables from .env file
5
+ load_dotenv()
6
+
7
+
8
+ class Config:
9
+ SECRET_KEY = os.getenv('SECRET_KEY', 'default_secret_key')
10
+ OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', None)
11
+
12
+ OUTPUT_FOLDER = os.path.join(os.path.abspath(os.curdir), 'ivoryos_data')
13
+ os.makedirs(OUTPUT_FOLDER, exist_ok=True)
14
+ CSV_FOLDER = os.path.join(OUTPUT_FOLDER, 'config_csv/')
15
+ SCRIPT_FOLDER = os.path.join(OUTPUT_FOLDER, 'scripts/')
16
+ DATA_FOLDER = os.path.join(OUTPUT_FOLDER, 'results/')
17
+ DUMMY_DECK = os.path.join(OUTPUT_FOLDER, 'pseudo_deck/')
18
+ LLM_OUTPUT = os.path.join(OUTPUT_FOLDER, 'llm_output/')
19
+ DECK_HISTORY = os.path.join(OUTPUT_FOLDER, 'deck_history.txt')
20
+ LOGGERS_PATH = "default.log"
21
+
22
+ SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(OUTPUT_FOLDER, 'ivoryos.db')}"
23
+ SQLALCHEMY_TRACK_MODIFICATIONS = False
24
+
25
+ ENABLE_LLM = True if OPENAI_API_KEY else False
26
+ OFF_LINE = True
27
+
28
+
29
+ class DevelopmentConfig(Config):
30
+ DEBUG = True
31
+
32
+
33
+ class ProductionConfig(Config):
34
+ DEBUG = False
35
+
36
+
37
+ class TestingConfig(Config):
38
+ DEBUG = True
39
+ TESTING = True
40
+
41
+
42
+ def get_config(env='dev'):
43
+ if env == 'production':
44
+ return ProductionConfig()
45
+ elif env == 'testing':
46
+ return TestingConfig()
47
+ return DevelopmentConfig()
@@ -1,65 +1,100 @@
1
- from flask import Blueprint, redirect, url_for, flash, request, render_template, session
2
- from flask_login import login_required, login_user, logout_user, LoginManager
3
- import bcrypt
4
-
5
- from ivoryos.utils.db_models import Script, User, db
6
- from ivoryos.utils.utils import post_script_file
7
- login_manager = LoginManager()
8
-
9
- auth = Blueprint('auth', __name__, template_folder='templates/auth')
10
-
11
-
12
- @auth.route('/login', methods=['GET', 'POST'])
13
- def login():
14
- if request.method == 'POST':
15
- username = request.form.get('username')
16
- password = request.form.get('password')
17
-
18
- # session.query(User, User.name).all()
19
- user = db.session.query(User).filter(User.username == username).first()
20
- input_password = password.encode('utf-8')
21
- # if user and bcrypt.checkpw(input_password, user.hashPassword.encode('utf-8')):
22
- if user and bcrypt.checkpw(input_password, user.hashPassword):
23
- # password.encode("utf-8")
24
- # user = User(username, password.encode("utf-8"))
25
- login_user(user)
26
- session['user'] = username
27
- script_file = Script(author=username)
28
- session["script"] = script_file.as_dict()
29
- session['hidden_functions'], session['card_order'], session['prompt'] = {}, {}, {}
30
- session['autofill'] = False
31
- post_script_file(script_file)
32
- return redirect(url_for('main.index'))
33
- else:
34
- flash("Incorrect username or password")
35
- return render_template('login.html')
36
-
37
-
38
- @auth.route('/signup', methods=['GET', 'POST'])
39
- def signup():
40
- if request.method == 'POST':
41
- username = request.form.get('username')
42
- password = request.form.get('password')
43
- salt = bcrypt.gensalt()
44
- hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
45
- user = User(username, hashed)
46
- try:
47
- db.session.add(user)
48
- db.session.commit()
49
- return redirect(url_for('auth.login'))
50
- except Exception:
51
- flash("username exists :(")
52
- return render_template('signup.html')
53
-
54
-
55
- @auth.route("/logout")
56
- @login_required
57
- def logout():
58
- logout_user()
59
- session.clear()
60
- return redirect(url_for('auth.login'))
61
-
62
-
63
- @login_manager.user_loader
64
- def load_user(username):
65
- return User(username, password=None)
1
+ from flask import Blueprint, redirect, url_for, flash, request, render_template, session
2
+ from flask_login import login_required, login_user, logout_user, LoginManager
3
+ import bcrypt
4
+
5
+ from ivoryos.utils.db_models import Script, User, db
6
+ from ivoryos.utils.utils import post_script_file
7
+ login_manager = LoginManager()
8
+
9
+ auth = Blueprint('auth', __name__, template_folder='templates/auth')
10
+
11
+
12
+ @auth.route('/login', methods=['GET', 'POST'])
13
+ def login():
14
+ """
15
+ .. :quickref: User; login user
16
+
17
+ .. http:get:: /login
18
+
19
+ load user login form.
20
+
21
+ .. http:post:: /login
22
+
23
+ :form username: username
24
+ :form password: password
25
+ :status 302: and then redirects to homepage
26
+ :status 401: incorrect password, redirects to :http:get:`/ivoryos/login`
27
+ """
28
+ if request.method == 'POST':
29
+ username = request.form.get('username')
30
+ password = request.form.get('password')
31
+
32
+ # session.query(User, User.name).all()
33
+ user = db.session.query(User).filter(User.username == username).first()
34
+ input_password = password.encode('utf-8')
35
+ # if user and bcrypt.checkpw(input_password, user.hashPassword.encode('utf-8')):
36
+ if user and bcrypt.checkpw(input_password, user.hashPassword):
37
+ # password.encode("utf-8")
38
+ # user = User(username, password.encode("utf-8"))
39
+ login_user(user)
40
+ session['user'] = username
41
+ script_file = Script(author=username)
42
+ session["script"] = script_file.as_dict()
43
+ session['hidden_functions'], session['card_order'], session['prompt'] = {}, {}, {}
44
+ session['autofill'] = False
45
+ post_script_file(script_file)
46
+ return redirect(url_for('main.index'))
47
+ else:
48
+ flash("Incorrect username or password")
49
+ return redirect(url_for('auth.login')), 401
50
+ return render_template('login.html')
51
+
52
+
53
+ @auth.route('/signup', methods=['GET', 'POST'])
54
+ def signup():
55
+ """
56
+ .. :quickref: User; signup for a new account
57
+
58
+ .. http:get:: /signup
59
+
60
+ load user sighup
61
+
62
+ .. http:post:: /signup
63
+
64
+ :form username: username
65
+ :form password: password
66
+ :status 302: and then redirects to :http:get:`/ivoryos/login`
67
+ :status 409: when user already exists, redirects to :http:get:`/ivoryos/signup`
68
+ """
69
+ if request.method == 'POST':
70
+ username = request.form.get('username')
71
+ password = request.form.get('password')
72
+ salt = bcrypt.gensalt()
73
+ hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
74
+ user = User(username, hashed)
75
+ try:
76
+ db.session.add(user)
77
+ db.session.commit()
78
+ return redirect(url_for('auth.login'))
79
+ except Exception:
80
+ flash("username exists :(", "error")
81
+ return render_template('signup.html'), 409
82
+ return render_template('signup.html')
83
+
84
+
85
+ @auth.route("/logout")
86
+ @login_required
87
+ def logout():
88
+ """
89
+ .. :quickref: User; logout the user
90
+
91
+ logout the current user, clear session info, and redirect to the login page.
92
+ """
93
+ logout_user()
94
+ session.clear()
95
+ return redirect(url_for('auth.login'))
96
+
97
+
98
+ @login_manager.user_loader
99
+ def load_user(username):
100
+ return User(username, password=None)
@@ -1,25 +1,25 @@
1
- {% extends 'base.html' %}
2
- {% block title %}IvoryOS | Login{% endblock %}
3
-
4
-
5
- {% block body %}
6
- <div class= "login">
7
- <div class="bg-white rounded shadow-sm flex-fill">
8
- <div class="p-4" style="align-items: center">
9
- <h5>Log in</h5>
10
- <form role="form" method='POST' name="login" action="{{ url_for('auth.login') }}">
11
- <div class="input-group mb-3">
12
- <label class="input-group-text" for="username">Username</label>
13
- <input class="form-control" type="text" id="username" name="username">
14
- </div>
15
- <div class="input-group mb-3">
16
- <label class="input-group-text" for="password">Password</label>
17
- <input class="form-control" type="password" id="password" name="password">
18
- </div>
19
- <button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">login</button>
20
- </form>
21
- <p class="message">Not registered? <a href="{{ url_for('auth.signup') }}">Create a new account</a>
22
- </div>
23
- </div>
24
- </div>
25
- {% endblock %}
1
+ {% extends 'base.html' %}
2
+ {% block title %}IvoryOS | Login{% endblock %}
3
+
4
+
5
+ {% block body %}
6
+ <div class= "login">
7
+ <div class="bg-white rounded shadow-sm flex-fill">
8
+ <div class="p-4" style="align-items: center">
9
+ <h5>Log in</h5>
10
+ <form role="form" method='POST' name="login" action="{{ url_for('auth.login') }}">
11
+ <div class="input-group mb-3">
12
+ <label class="input-group-text" for="username">Username</label>
13
+ <input class="form-control" type="text" id="username" name="username">
14
+ </div>
15
+ <div class="input-group mb-3">
16
+ <label class="input-group-text" for="password">Password</label>
17
+ <input class="form-control" type="password" id="password" name="password">
18
+ </div>
19
+ <button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">login</button>
20
+ </form>
21
+ <p class="message">Not registered? <a href="{{ url_for('auth.signup') }}">Create a new account</a>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ {% endblock %}
@@ -1,32 +1,32 @@
1
- {% extends 'base.html' %}
2
- {% block title %}IvoryOS | Signup{% endblock %}
3
-
4
-
5
- {% block body %}
6
- <div class= "login">
7
- <div class="bg-white rounded shadow-sm flex-fill">
8
- <div class="p-4" style="align: center">
9
- <h5>Create a new account</h5>
10
- <form role="form" method='POST' name="signup" action="{{ url_for('auth.signup') }}">
11
-
12
- <div class="input-group mb-3">
13
- <label class="input-group-text" for="username">Username</label>
14
- <input class="form-control" type="text" id="username" name="username" required>
15
- </div>
16
- <div class="input-group mb-3">
17
- <label class="input-group-text" for="password">Password</label>
18
- <input class="form-control" type="password" id="password" name="password" required>
19
- </div>
20
- {# <div class="input-group mb-3">#}
21
- {# <label class="input-group-text" for="confirm_password">Confirm Password</label>#}
22
- {# <input class="form-control" type="confirm_password" id="confirm_password" name="confirm_password">#}
23
- {# </div>#}
24
-
25
- <button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">Sign up</button>
26
- </form>
27
- <p class="message" >Already registered? <a href="{{ url_for('auth.login') }}">Sign In</a></p>
28
- </div>
29
- </div>
30
- </div>
31
-
32
- {% endblock %}
1
+ {% extends 'base.html' %}
2
+ {% block title %}IvoryOS | Signup{% endblock %}
3
+
4
+
5
+ {% block body %}
6
+ <div class= "login">
7
+ <div class="bg-white rounded shadow-sm flex-fill">
8
+ <div class="p-4" style="align: center">
9
+ <h5>Create a new account</h5>
10
+ <form role="form" method='POST' name="signup" action="{{ url_for('auth.signup') }}">
11
+
12
+ <div class="input-group mb-3">
13
+ <label class="input-group-text" for="username">Username</label>
14
+ <input class="form-control" type="text" id="username" name="username" required>
15
+ </div>
16
+ <div class="input-group mb-3">
17
+ <label class="input-group-text" for="password">Password</label>
18
+ <input class="form-control" type="password" id="password" name="password" required>
19
+ </div>
20
+ {# <div class="input-group mb-3">#}
21
+ {# <label class="input-group-text" for="confirm_password">Confirm Password</label>#}
22
+ {# <input class="form-control" type="confirm_password" id="confirm_password" name="confirm_password">#}
23
+ {# </div>#}
24
+
25
+ <button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">Sign up</button>
26
+ </form>
27
+ <p class="message" >Already registered? <a href="{{ url_for('auth.login') }}">Sign In</a></p>
28
+ </div>
29
+ </div>
30
+ </div>
31
+
32
+ {% endblock %}