mirror of
https://github.com/fsecada01/Pygentic-AI.git
synced 2025-06-15 11:36:03 +00:00
adding HTML components for HTMX integration
This commit is contained in:
parent
012ef4cc04
commit
0e65c811a1
2
.gitignore
vendored
2
.gitignore
vendored
@ -160,4 +160,4 @@ celerybeat-schedule*
|
|||||||
.ruff_cache
|
.ruff_cache
|
||||||
|
|
||||||
# JS dependencies
|
# JS dependencies
|
||||||
node_modules
|
node_modules
|
||||||
|
@ -2,33 +2,24 @@ repos:
|
|||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v5.0.0
|
rev: v5.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-added-large-files
|
|
||||||
- id: check-ast
|
- id: check-ast
|
||||||
- id: check-builtin-literals
|
|
||||||
- id: check-case-conflict
|
|
||||||
- id: check-docstring-first
|
|
||||||
- id: check-executables-have-shebangs
|
|
||||||
- id: check-json
|
- id: check-json
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-shebang-scripts-are-executable
|
|
||||||
- id: check-symlinks
|
|
||||||
- id: check-toml
|
|
||||||
- id: check-vcs-permalinks
|
|
||||||
- id: check-xml
|
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
- id: check-builtin-literals
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
exclude: tests/
|
|
||||||
- id: destroyed-symlinks
|
- id: destroyed-symlinks
|
||||||
# - id: detect-aws-credentials
|
|
||||||
- id: detect-private-key
|
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
exclude: tests/test_changes/
|
- id: mixed-line-ending
|
||||||
files: \.(py|sh|rst|yml|yaml)$
|
|
||||||
- id: fix-byte-order-marker
|
|
||||||
- id: pretty-format-json
|
|
||||||
args: [--autofix]
|
|
||||||
- id: sort-simple-yaml
|
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
- hooks:
|
||||||
|
- id: add-trailing-comma
|
||||||
|
repo: 'https://github.com/asottile/add-trailing-comma'
|
||||||
|
rev: v3.1.0
|
||||||
|
- hooks:
|
||||||
|
- id: pyupgrade
|
||||||
|
repo: 'https://github.com/asottile/pyupgrade'
|
||||||
|
rev: v3.19.1
|
||||||
|
|
||||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||||
# Ruff version.
|
# Ruff version.
|
||||||
@ -52,4 +43,4 @@ repos:
|
|||||||
rev: v3.19.1
|
rev: v3.19.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py311-plus]
|
args: [--py313-plus]
|
||||||
|
@ -34,4 +34,4 @@ RUN mkdir -p /tmp/log/celery && \
|
|||||||
RUN find . -name "*.sh" -exec chmod +x {} \;
|
RUN find . -name "*.sh" -exec chmod +x {} \;
|
||||||
RUN echo $WORKDIR
|
RUN echo $WORKDIR
|
||||||
RUN /bin/bash -c 'source $WORKDIR/docker/pygentic_ai/python_build.sh'
|
RUN /bin/bash -c 'source $WORKDIR/docker/pygentic_ai/python_build.sh'
|
||||||
CMD /bin/bash -c 'source $WORKDIR/docker/pygentic_ai/python_start.sh'
|
CMD /bin/bash -c 'source $WORKDIR/docker/pygentic_ai/python_start.sh'
|
||||||
|
@ -7,4 +7,4 @@ isort
|
|||||||
jupyterlab
|
jupyterlab
|
||||||
jupyterlab-code-formatter
|
jupyterlab-code-formatter
|
||||||
pre-commit
|
pre-commit
|
||||||
ruff
|
ruff
|
||||||
|
@ -20,7 +20,8 @@ app = create_app(debug=debug_arg, settings_obj=app_settings)
|
|||||||
|
|
||||||
@app.exception_handler(RequestValidationError)
|
@app.exception_handler(RequestValidationError)
|
||||||
async def validation_exception_handler(
|
async def validation_exception_handler(
|
||||||
request: Request, exc: RequestValidationError
|
request: Request,
|
||||||
|
exc: RequestValidationError,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Custom validation error messaging for end-users. This reduces ambiguity
|
Custom validation error messaging for end-users. This reduces ambiguity
|
||||||
@ -35,7 +36,8 @@ async def validation_exception_handler(
|
|||||||
content = {"status_code": 10422, "message": exc_str, "data": None}
|
content = {"status_code": 10422, "message": exc_str, "data": None}
|
||||||
|
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY
|
content=content,
|
||||||
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ async def unicorn_exception_handler(request: Request, exc: UnicornException):
|
|||||||
status_code=418,
|
status_code=418,
|
||||||
content={
|
content={
|
||||||
"message": f"Oops! {exc.name} did something. "
|
"message": f"Oops! {exc.name} did something. "
|
||||||
"There goes a rainbow..."
|
"There goes a rainbow...",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ from backend.logger import logger
|
|||||||
|
|
||||||
@swot_agent.tool(prepare=report_tool_usage)
|
@swot_agent.tool(prepare=report_tool_usage)
|
||||||
async def fetch_website_content(
|
async def fetch_website_content(
|
||||||
_ctx: RunContext[SwotAgentDeps], url: str
|
_ctx: RunContext[SwotAgentDeps],
|
||||||
|
url: str,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Fetches the HTML content of the given URL via httpx and beautifulsoup
|
Fetches the HTML content of the given URL via httpx and beautifulsoup
|
||||||
@ -70,7 +71,9 @@ async def analyze_competition(
|
|||||||
|
|
||||||
@swot_agent.tool(prepare=report_tool_usage)
|
@swot_agent.tool(prepare=report_tool_usage)
|
||||||
async def get_reddit_insights(
|
async def get_reddit_insights(
|
||||||
ctx: RunContext[SwotAgentDeps], query: str, subreddit_name: str = "python"
|
ctx: RunContext[SwotAgentDeps],
|
||||||
|
query: str,
|
||||||
|
subreddit_name: str = "python",
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
A tool to gain insights from a subreddit. Data is returned as string
|
A tool to gain insights from a subreddit. Data is returned as string
|
||||||
@ -89,14 +92,15 @@ async def get_reddit_insights(
|
|||||||
insights.append(
|
insights.append(
|
||||||
f"Title: {post.title}\n"
|
f"Title: {post.title}\n"
|
||||||
f"URL: {post.url}\n"
|
f"URL: {post.url}\n"
|
||||||
f"Content: {post.selftext}\n"
|
f"Content: {post.selftext}\n",
|
||||||
)
|
)
|
||||||
|
|
||||||
return "\n".join(insights)
|
return "\n".join(insights)
|
||||||
|
|
||||||
|
|
||||||
async def run_agent(
|
async def run_agent(
|
||||||
url: str, deps: SwotAgentDeps = SwotAgentDeps()
|
url: str,
|
||||||
|
deps: SwotAgentDeps = SwotAgentDeps(),
|
||||||
) -> SwotAnalysis | Exception:
|
) -> SwotAnalysis | Exception:
|
||||||
"""
|
"""
|
||||||
Runs the SWOT Analysis Agent
|
Runs the SWOT Analysis Agent
|
||||||
|
@ -5,7 +5,8 @@ from backend.core.core import SwotAgentDeps
|
|||||||
|
|
||||||
|
|
||||||
async def report_tool_usage(
|
async def report_tool_usage(
|
||||||
ctx: RunContext[SwotAgentDeps], tool_def: ToolDefinition
|
ctx: RunContext[SwotAgentDeps],
|
||||||
|
tool_def: ToolDefinition,
|
||||||
) -> ToolDefinition:
|
) -> ToolDefinition:
|
||||||
"""
|
"""
|
||||||
Reports tool usage + results to an update function
|
Reports tool usage + results to an update function
|
||||||
@ -18,7 +19,8 @@ async def report_tool_usage(
|
|||||||
|
|
||||||
if ctx.deps.update_status_func:
|
if ctx.deps.update_status_func:
|
||||||
await ctx.deps.update_status_func(
|
await ctx.deps.update_status_func(
|
||||||
ctx.deps.request, f"Using tool: {tool_def.name}..."
|
ctx.deps.request,
|
||||||
|
f"Using tool: {tool_def.name}...",
|
||||||
)
|
)
|
||||||
ctx.deps.tool_history.append(tool_def.name)
|
ctx.deps.tool_history.append(tool_def.name)
|
||||||
|
|
||||||
|
@ -38,7 +38,9 @@ def as_form(cls: type[BaseModel]):
|
|||||||
inspect.Parameter.POSITIONAL_ONLY,
|
inspect.Parameter.POSITIONAL_ONLY,
|
||||||
default=model_field.default,
|
default=model_field.default,
|
||||||
annotation=Annotated[
|
annotation=Annotated[
|
||||||
model_field.annotation, *model_field.metadata, Form()
|
model_field.annotation,
|
||||||
|
*model_field.metadata,
|
||||||
|
Form(),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
for field_name, model_field in cls.model_fields.items()
|
for field_name, model_field in cls.model_fields.items()
|
||||||
@ -56,7 +58,7 @@ def as_form(cls: type[BaseModel]):
|
|||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
async def get_async_session() -> AsyncGenerator[AsyncSession, None]:
|
async def get_async_session() -> AsyncGenerator[AsyncSession]:
|
||||||
"""
|
"""
|
||||||
Get async SQLA session via generator function
|
Get async SQLA session via generator function
|
||||||
"""
|
"""
|
||||||
@ -88,7 +90,7 @@ async def run_out_of_band(
|
|||||||
"""
|
"""
|
||||||
async with async_sessionaker() as oob_session:
|
async with async_sessionaker() as oob_session:
|
||||||
await oob_session.connection(
|
await oob_session.connection(
|
||||||
execution_options={"isolation_level": "AUTOCOMMIT"}
|
execution_options={"isolation_level": "AUTOCOMMIT"},
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await oob_session.execute(statement)
|
result = await oob_session.execute(statement)
|
||||||
@ -96,7 +98,10 @@ async def run_out_of_band(
|
|||||||
if merge_results:
|
if merge_results:
|
||||||
return (
|
return (
|
||||||
await session_inst.run_sync(
|
await session_inst.run_sync(
|
||||||
merge_frozen_result, statement, result.freeze(), load=False
|
merge_frozen_result,
|
||||||
|
statement,
|
||||||
|
result.freeze(),
|
||||||
|
load=False,
|
||||||
)
|
)
|
||||||
)()
|
)()
|
||||||
else:
|
else:
|
||||||
@ -114,7 +119,7 @@ async def check_db_exists(engine_inst):
|
|||||||
from sqlalchemy import inspect # noqa
|
from sqlalchemy import inspect # noqa
|
||||||
|
|
||||||
tables = await conn.run_sync(
|
tables = await conn.run_sync(
|
||||||
lambda sync_conn: inspect(sync_conn).get_table_names()
|
lambda sync_conn: inspect(sync_conn).get_table_names(),
|
||||||
)
|
)
|
||||||
logger.info(tables)
|
logger.info(tables)
|
||||||
if not tables:
|
if not tables:
|
||||||
@ -146,7 +151,9 @@ async def create_db(
|
|||||||
|
|
||||||
|
|
||||||
def create_db_engine(
|
def create_db_engine(
|
||||||
db_url: str, async_bool: bool = False, echo_bool: bool = False
|
db_url: str,
|
||||||
|
async_bool: bool = False,
|
||||||
|
echo_bool: bool = False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -194,11 +201,15 @@ sync_engine = create_db_engine(db_url, echo_bool=echo)
|
|||||||
session_inst = Session(sync_engine, expire_on_commit=False)
|
session_inst = Session(sync_engine, expire_on_commit=False)
|
||||||
|
|
||||||
async_session_maker = sessionmaker(
|
async_session_maker = sessionmaker(
|
||||||
bind=engine, class_=AsyncSession, expire_on_commit=False
|
bind=engine,
|
||||||
|
class_=AsyncSession,
|
||||||
|
expire_on_commit=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
session_maker = sessionmaker(
|
session_maker = sessionmaker(
|
||||||
bind=engine, class_=Session, expire_on_commit=False
|
bind=engine,
|
||||||
|
class_=Session,
|
||||||
|
expire_on_commit=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -26,7 +26,7 @@ list(
|
|||||||
enqueue=True,
|
enqueue=True,
|
||||||
),
|
),
|
||||||
["info", "debug", "error", "success", "warning", "critical"],
|
["info", "debug", "error", "success", "warning", "critical"],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +53,8 @@ class InterceptHandler(logging.Handler):
|
|||||||
|
|
||||||
log = logger.bind(request_id="app")
|
log = logger.bind(request_id="app")
|
||||||
log.opt(depth=depth, exception=record.exc_info).log(
|
log.opt(depth=depth, exception=record.exc_info).log(
|
||||||
level, record.getMessage()
|
level,
|
||||||
|
record.getMessage(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ from backend.settings.prod import Settings as ProdSettings
|
|||||||
from backend.utils import get_val
|
from backend.utils import get_val
|
||||||
|
|
||||||
server_types = enum.StrEnum(
|
server_types = enum.StrEnum(
|
||||||
"ServerTypes", {x.upper(): x for x in ("dev", "uat", "staging", "prod")}
|
"ServerTypes",
|
||||||
|
{x.upper(): x for x in ("dev", "uat", "staging", "prod")},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ def get_db_val(
|
|||||||
[
|
[
|
||||||
hasattr(db_configs, x)
|
hasattr(db_configs, x)
|
||||||
for x in ("name", "user", "password", "host", "port", "kwargs")
|
for x in ("name", "user", "password", "host", "port", "kwargs")
|
||||||
]
|
],
|
||||||
):
|
):
|
||||||
url = f"{dialect}:{schema_sep}{db_configs.host}"
|
url = f"{dialect}:{schema_sep}{db_configs.host}"
|
||||||
else:
|
else:
|
||||||
|
@ -47,7 +47,7 @@ all_dialects = enum.Enum(
|
|||||||
y
|
y
|
||||||
for x in (pg_dialects, mysql_dialects, sqlite_dialects)
|
for x in (pg_dialects, mysql_dialects, sqlite_dialects)
|
||||||
for y in x
|
for y in x
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -26,10 +26,10 @@ catalog = Catalog(jinja_env=templates.env)
|
|||||||
list(
|
list(
|
||||||
map(
|
map(
|
||||||
lambda folder: catalog.add_folder(
|
lambda folder: catalog.add_folder(
|
||||||
os.path.join(frontend, "components", folder) # noqa
|
os.path.join(frontend, "components", folder), # noqa
|
||||||
),
|
),
|
||||||
("main", "forms", "snippets"),
|
("main", "forms", "snippets"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
user_frontend.mount(
|
user_frontend.mount(
|
||||||
@ -87,7 +87,7 @@ async def get_status(request: Request):
|
|||||||
result = ANALYSIS_COMPLETE_MESSAGE in messages
|
result = ANALYSIS_COMPLETE_MESSAGE in messages
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Status check - Session ID: {'session_id'}, Messages: "
|
f"Status check - Session ID: {'session_id'}, Messages: "
|
||||||
f"{messages}"
|
f"{messages}",
|
||||||
)
|
)
|
||||||
|
|
||||||
context.update({"messages": messages, "result": result})
|
context.update({"messages": messages, "result": result})
|
||||||
|
@ -46,11 +46,14 @@ async def update_status(session_id: str, message: Any) -> None:
|
|||||||
else:
|
else:
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
await loop.run_in_executor(
|
await loop.run_in_executor(
|
||||||
None, emulate_tool_completion, session_id, message
|
None,
|
||||||
|
emulate_tool_completion,
|
||||||
|
session_id,
|
||||||
|
message,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Status messages for session {session_id}: {status_store[session_id]}"
|
f"Status messages for session {session_id}: {status_store[session_id]}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -67,7 +70,8 @@ async def run_agent_with_progress(session_id, url):
|
|||||||
deps = SwotAgentDeps(
|
deps = SwotAgentDeps(
|
||||||
request=None,
|
request=None,
|
||||||
update_status_func=lambda request, msg: update_status(
|
update_status_func=lambda request, msg: update_status(
|
||||||
session_id, msg
|
session_id,
|
||||||
|
msg,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -78,7 +82,7 @@ async def run_agent_with_progress(session_id, url):
|
|||||||
result_store[session_id] = result
|
result_store[session_id] = result
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
f"An unexpected error occurred. See here: " f"{type(e), e, e.args}"
|
f"An unexpected error occurred. See here: " f"{type(e), e, e.args}",
|
||||||
)
|
)
|
||||||
await update_status(session_id, f"Unexpected error: {e}")
|
await update_status(session_id, f"Unexpected error: {e}")
|
||||||
raise
|
raise
|
||||||
|
@ -62,7 +62,7 @@ def get_val(val: str, default: str | int | bool | None = None, **kwargs):
|
|||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Env Var {val} is not populated in the environment "
|
f"Env Var {val} is not populated in the environment "
|
||||||
f"or within the configuration files"
|
f"or within the configuration files",
|
||||||
)
|
)
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
1
src/frontend/static/css/bulma-collapsible.min.css
vendored
Normal file
1
src/frontend/static/css/bulma-collapsible.min.css
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
@-webkit-keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spinAround{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.is-collapsible{overflow-y:hidden;transition:height .2s ease}.is-collapsible.is-active{transition:height .2s ease}.is-collapsible.message-body{padding:0!important}.is-collapsible.message-body .message-body-content{padding:1.25em 1.5em}
|
21559
src/frontend/static/css/bulma.css
vendored
Normal file
21559
src/frontend/static/css/bulma.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
src/frontend/static/css/bulma.css.map
Normal file
1
src/frontend/static/css/bulma.css.map
Normal file
File diff suppressed because one or more lines are too long
3
src/frontend/static/css/bulma.min.css
vendored
Normal file
3
src/frontend/static/css/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
src/frontend/static/css/bulma.scss
vendored
Normal file
4
src/frontend/static/css/bulma.scss
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
@charset "utf-8";
|
||||||
|
|
||||||
|
/*! bulma.io v1.0.3 | MIT License | github.com/jgthms/bulma */
|
||||||
|
@use "sass";
|
1
src/frontend/static/js/bulma-collapsible.min.js
vendored
Normal file
1
src/frontend/static/js/bulma-collapsible.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/frontend/static/js/bulma.js
Normal file
1
src/frontend/static/js/bulma.js
Normal file
File diff suppressed because one or more lines are too long
56
src/frontend/static/js/htmx.js
Normal file
56
src/frontend/static/js/htmx.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// build a --template, or a whole project --root directory
|
||||||
|
// default context filename is `index.js` for dirs, unless --context
|
||||||
|
// specify a --build directory to output there, instead of STDOUT
|
||||||
|
|
||||||
|
var
|
||||||
|
preprocess= require('./preprocess'),
|
||||||
|
// here you can pre-process the response before final output
|
||||||
|
|
||||||
|
DELIM= ["::", "::"], // or use ["<\\?js", "\\?>"] to get `1<?js2?>3` → `123`
|
||||||
|
// describe your document context in JSON, then use <?js ?> for the template
|
||||||
|
// i.e. root/index.json {a:1, b:"hi"} , index.html <!doctype html> ::b+a:: → "hi1"
|
||||||
|
|
||||||
|
JSON= /^\s*\{[^]*\}\s*$/gi
|
||||||
|
// relaxed Javascript Object, for use with eval([js]).pop()
|
||||||
|
|
||||||
|
|
||||||
|
function HTMX (delim){
|
||||||
|
function unpickle (__ctx, __js){ with (__ctx){ return eval (__js) }}
|
||||||
|
|
||||||
|
var
|
||||||
|
EMPTY_STR= '',
|
||||||
|
NOT_DELIM= ANY= "([^]*?)"
|
||||||
|
|
||||||
|
return (function (delim, pre){
|
||||||
|
return function renderTemplateWithContext (t, c){
|
||||||
|
var
|
||||||
|
r= t.split( new RegExp(delim.join( NOT_DELIM), 'ig')),
|
||||||
|
n= 0, s,
|
||||||
|
c= c || {}
|
||||||
|
|
||||||
|
do {
|
||||||
|
s= 3 *n + 1
|
||||||
|
if (r[s] && r[s].match( JSON)){
|
||||||
|
|
||||||
|
r[s]= unpickle( c, '[' + r[s] + ']')[0]
|
||||||
|
r[s]= pre.call( c, r[s])
|
||||||
|
r[s]= r[s].return
|
||||||
|
} else {
|
||||||
|
r[s]= unpickle( c, r[s])
|
||||||
|
}
|
||||||
|
n += 1
|
||||||
|
} while (void 0 !== r[3 *n])
|
||||||
|
return r.join(EMPTY_STR)
|
||||||
|
}
|
||||||
|
})(delim || DELIM, preprocess)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (require.main === module){
|
||||||
|
if (2 >= process.argv.length)
|
||||||
|
throw new Error("use --root with --build, or --template with --context")
|
||||||
|
require('./cli')(HTMX)
|
||||||
|
|
||||||
|
} else
|
||||||
|
module.exports= HTMX
|
10716
src/frontend/static/js/jquery.js
vendored
Normal file
10716
src/frontend/static/js/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
src/frontend/static/js/jquery.min.js
vendored
Normal file
2
src/frontend/static/js/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
src/frontend/static/js/jquery.min.map
Normal file
1
src/frontend/static/js/jquery.min.map
Normal file
File diff suppressed because one or more lines are too long
0
src/frontend/templates/components/main/Footer.jinja
Normal file
0
src/frontend/templates/components/main/Footer.jinja
Normal file
9
src/frontend/templates/components/main/Header.jinja
Normal file
9
src/frontend/templates/components/main/Header.jinja
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{# def
|
||||||
|
title: str
|
||||||
|
#}
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
{{ slot }}
|
||||||
|
</head>
|
0
src/frontend/templates/components/main/Nav.jinja
Normal file
0
src/frontend/templates/components/main/Nav.jinja
Normal file
17
src/frontend/templates/components/snippets/Base.jinja
Normal file
17
src/frontend/templates/components/snippets/Base.jinja
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<Header title="Pygentic AI">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE-edge, chrome=1">
|
||||||
|
<Css url="{{ url_for('static', path='/css/bulma.min.css') }}"></Css>
|
||||||
|
<Css url="{{ url_for('static', path='/css/bulma-calendar.min.css') }}"></Css>
|
||||||
|
<Css url="{{ url_for('static', path='/css/bulmatags-input.min-css') }}"></Css>
|
||||||
|
<Css url="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
||||||
|
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
|
||||||
|
crossorigin="anonymous"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
</Css>
|
||||||
|
</Header>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
9
src/frontend/templates/components/snippets/Css.jinja
Normal file
9
src/frontend/templates/components/snippets/Css.jinja
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{# def
|
||||||
|
url: str,
|
||||||
|
rel: str = 'stylesheet'
|
||||||
|
#}
|
||||||
|
|
||||||
|
<link rel={{ rel }}
|
||||||
|
href={{ url }}
|
||||||
|
{{ slot }}
|
||||||
|
/>
|
8
src/frontend/templates/components/snippets/Js.jinja
Normal file
8
src/frontend/templates/components/snippets/Js.jinja
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{# def
|
||||||
|
url: str
|
||||||
|
#}
|
||||||
|
|
||||||
|
<script
|
||||||
|
src={{ url }}
|
||||||
|
{{ slot }}
|
||||||
|
></script>
|
Loading…
x
Reference in New Issue
Block a user