Spaces:
Sleeping
Sleeping
rsm-roguchi
commited on
Commit
·
a36cd3b
1
Parent(s):
ca5301a
pytrends working
Browse files- app.py +4 -1
- pyproject.toml +1 -0
- server/blog.py +72 -19
- ui/blog.py +6 -1
- uv.lock +52 -0
- www/style.css +26 -0
app.py
CHANGED
|
@@ -14,7 +14,10 @@ from server import (
|
|
| 14 |
ui = ui.page_fluid(
|
| 15 |
ui.page_navbar(
|
| 16 |
blog.ui,
|
| 17 |
-
title="SEO Blog Writer"
|
|
|
|
|
|
|
|
|
|
| 18 |
)
|
| 19 |
)
|
| 20 |
|
|
|
|
| 14 |
ui = ui.page_fluid(
|
| 15 |
ui.page_navbar(
|
| 16 |
blog.ui,
|
| 17 |
+
title="SEO Blog Writer",
|
| 18 |
+
header=ui.tags.head(
|
| 19 |
+
ui.tags.link(rel='stylesheet', type='text/css', href='style.css')
|
| 20 |
+
)
|
| 21 |
)
|
| 22 |
)
|
| 23 |
|
pyproject.toml
CHANGED
|
@@ -18,5 +18,6 @@ dependencies = [
|
|
| 18 |
"pydantic-ai>=0.3.5",
|
| 19 |
"pyrsm>=1.6.0",
|
| 20 |
"python-dotenv>=1.1.1",
|
|
|
|
| 21 |
"requests>=2.32.4",
|
| 22 |
]
|
|
|
|
| 18 |
"pydantic-ai>=0.3.5",
|
| 19 |
"pyrsm>=1.6.0",
|
| 20 |
"python-dotenv>=1.1.1",
|
| 21 |
+
"pytrends>=4.9.2",
|
| 22 |
"requests>=2.32.4",
|
| 23 |
]
|
server/blog.py
CHANGED
|
@@ -1,28 +1,81 @@
|
|
| 1 |
-
from shiny import reactive, render
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from llm_connect import get_response
|
| 3 |
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
)
|
| 20 |
|
|
|
|
|
|
|
| 21 |
def server(input, output, session):
|
|
|
|
|
|
|
|
|
|
| 22 |
@output
|
| 23 |
-
@render.
|
| 24 |
-
|
|
|
|
| 25 |
topic = input.topic()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
if not topic:
|
| 27 |
-
return "
|
| 28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from shiny import reactive, render, ui
|
| 2 |
+
import sys, os
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
from pytrends.request import TrendReq
|
| 5 |
+
|
| 6 |
+
load_dotenv()
|
| 7 |
+
|
| 8 |
+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "code")))
|
| 9 |
from llm_connect import get_response
|
| 10 |
|
| 11 |
+
import warnings
|
| 12 |
+
warnings.filterwarnings("ignore", category=FutureWarning)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def get_related_keywords(topic: str, region="US", top_n=5) -> list:
|
| 16 |
+
pytrends = TrendReq(hl="en-US", tz=360)
|
| 17 |
+
suggestions = pytrends.suggestions(keyword=topic)
|
| 18 |
+
keywords = [s["title"] for s in suggestions if topic.lower() not in s["title"].lower()]
|
| 19 |
+
|
| 20 |
+
if not keywords:
|
| 21 |
+
return []
|
| 22 |
|
| 23 |
+
pytrends.build_payload(keywords[:10], timeframe='now 7-d', geo=region)
|
| 24 |
+
df = pytrends.interest_over_time()
|
| 25 |
+
|
| 26 |
+
top_keywords = (
|
| 27 |
+
df.drop(columns=["isPartial"])
|
| 28 |
+
.mean()
|
| 29 |
+
.sort_values(ascending=False)
|
| 30 |
+
.head(top_n)
|
| 31 |
+
.index.tolist()
|
| 32 |
)
|
| 33 |
|
| 34 |
+
return top_keywords
|
| 35 |
+
|
| 36 |
def server(input, output, session):
|
| 37 |
+
# Reactive store for extracted keywords
|
| 38 |
+
related_keywords = reactive.Value([])
|
| 39 |
+
|
| 40 |
@output
|
| 41 |
+
@render.ui
|
| 42 |
+
@reactive.event(input.generate_btn)
|
| 43 |
+
def blog_result():
|
| 44 |
topic = input.topic()
|
| 45 |
+
|
| 46 |
+
print("[DEBUG] Button clicked.")
|
| 47 |
+
print(f"[DEBUG] Topic: {topic}")
|
| 48 |
+
|
| 49 |
if not topic:
|
| 50 |
+
return ui.HTML("<p><strong>⚠️ Please enter a topic before generating.</strong></p>")
|
| 51 |
+
|
| 52 |
+
# Get SEO keywords and store
|
| 53 |
+
keywords = get_related_keywords(topic)
|
| 54 |
+
related_keywords.set(keywords)
|
| 55 |
+
|
| 56 |
+
keyword_str = ", ".join(keywords) if keywords else topic
|
| 57 |
+
|
| 58 |
+
prompt = (
|
| 59 |
+
f"You are a blog writer for a hobby company called 'Ultima Supply'.\n"
|
| 60 |
+
f"Write an SEO-optimized blog in HTML format using the following keywords throughout: {keyword_str}.\n"
|
| 61 |
+
f"Make sure to use proper <h1>, <h2>, and <p> tags. Topic: {topic}"
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
blog_output = get_response(
|
| 65 |
+
input=prompt,
|
| 66 |
+
template=lambda x: x,
|
| 67 |
+
llm='llama',
|
| 68 |
+
md=False,
|
| 69 |
+
temperature=0.8,
|
| 70 |
+
max_tokens=1000
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
return ui.HTML(blog_output)
|
| 74 |
+
|
| 75 |
+
@output
|
| 76 |
+
@render.text
|
| 77 |
+
def keywords_used():
|
| 78 |
+
kws = related_keywords()
|
| 79 |
+
if not kws:
|
| 80 |
+
return "No SEO keywords retrieved yet."
|
| 81 |
+
return f"SEO Keywords Injected: {', '.join(kws)}"
|
ui/blog.py
CHANGED
|
@@ -3,5 +3,10 @@ from shiny import ui
|
|
| 3 |
ui = ui.nav_panel(
|
| 4 |
"Blog Writer",
|
| 5 |
ui.input_text("topic", "Enter Blog Topic", placeholder="e.g. Best One Piece Cards in 2025"),
|
| 6 |
-
ui.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
)
|
|
|
|
| 3 |
ui = ui.nav_panel(
|
| 4 |
"Blog Writer",
|
| 5 |
ui.input_text("topic", "Enter Blog Topic", placeholder="e.g. Best One Piece Cards in 2025"),
|
| 6 |
+
ui.div(
|
| 7 |
+
ui.input_action_button("generate_btn", "Generate Blog"),
|
| 8 |
+
class_="mt-3 mb-3"
|
| 9 |
+
),
|
| 10 |
+
ui.output_ui("blog_result"),
|
| 11 |
+
ui.output_text('keywords_used')
|
| 12 |
)
|
uv.lock
CHANGED
|
@@ -1465,6 +1465,42 @@ wheels = [
|
|
| 1465 |
{ url = "https://files.pythonhosted.org/packages/8a/56/c12e4222b312146e8a0979f59ac326980b46bb356292145f2e08a47bb907/logfire_api-3.21.2-py3-none-any.whl", hash = "sha256:14ae7689be6ad51ce68f2009bade1e4c804f01e17e435ab9ecb11c799ff027a2", size = 82623 },
|
| 1466 |
]
|
| 1467 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1468 |
[[package]]
|
| 1469 |
name = "markdown-it-py"
|
| 1470 |
version = "3.0.0"
|
|
@@ -2415,6 +2451,20 @@ wheels = [
|
|
| 2415 |
{ url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 },
|
| 2416 |
]
|
| 2417 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2418 |
[[package]]
|
| 2419 |
name = "pytz"
|
| 2420 |
version = "2025.2"
|
|
@@ -3158,6 +3208,7 @@ dependencies = [
|
|
| 3158 |
{ name = "pydantic-ai" },
|
| 3159 |
{ name = "pyrsm" },
|
| 3160 |
{ name = "python-dotenv" },
|
|
|
|
| 3161 |
{ name = "requests" },
|
| 3162 |
]
|
| 3163 |
|
|
@@ -3176,6 +3227,7 @@ requires-dist = [
|
|
| 3176 |
{ name = "pydantic-ai", specifier = ">=0.3.5" },
|
| 3177 |
{ name = "pyrsm", specifier = ">=1.6.0" },
|
| 3178 |
{ name = "python-dotenv", specifier = ">=1.1.1" },
|
|
|
|
| 3179 |
{ name = "requests", specifier = ">=2.32.4" },
|
| 3180 |
]
|
| 3181 |
|
|
|
|
| 1465 |
{ url = "https://files.pythonhosted.org/packages/8a/56/c12e4222b312146e8a0979f59ac326980b46bb356292145f2e08a47bb907/logfire_api-3.21.2-py3-none-any.whl", hash = "sha256:14ae7689be6ad51ce68f2009bade1e4c804f01e17e435ab9ecb11c799ff027a2", size = 82623 },
|
| 1466 |
]
|
| 1467 |
|
| 1468 |
+
[[package]]
|
| 1469 |
+
name = "lxml"
|
| 1470 |
+
version = "6.0.0"
|
| 1471 |
+
source = { registry = "https://pypi.org/simple" }
|
| 1472 |
+
sdist = { url = "https://files.pythonhosted.org/packages/c5/ed/60eb6fa2923602fba988d9ca7c5cdbd7cf25faa795162ed538b527a35411/lxml-6.0.0.tar.gz", hash = "sha256:032e65120339d44cdc3efc326c9f660f5f7205f3a535c1fdbf898b29ea01fb72", size = 4096938 }
|
| 1473 |
+
wheels = [
|
| 1474 |
+
{ url = "https://files.pythonhosted.org/packages/89/c3/d01d735c298d7e0ddcedf6f028bf556577e5ab4f4da45175ecd909c79378/lxml-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78718d8454a6e928470d511bf8ac93f469283a45c354995f7d19e77292f26108", size = 8429515 },
|
| 1475 |
+
{ url = "https://files.pythonhosted.org/packages/06/37/0e3eae3043d366b73da55a86274a590bae76dc45aa004b7042e6f97803b1/lxml-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:84ef591495ffd3f9dcabffd6391db7bb70d7230b5c35ef5148354a134f56f2be", size = 4601387 },
|
| 1476 |
+
{ url = "https://files.pythonhosted.org/packages/a3/28/e1a9a881e6d6e29dda13d633885d13acb0058f65e95da67841c8dd02b4a8/lxml-6.0.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:2930aa001a3776c3e2601cb8e0a15d21b8270528d89cc308be4843ade546b9ab", size = 5228928 },
|
| 1477 |
+
{ url = "https://files.pythonhosted.org/packages/9a/55/2cb24ea48aa30c99f805921c1c7860c1f45c0e811e44ee4e6a155668de06/lxml-6.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:219e0431ea8006e15005767f0351e3f7f9143e793e58519dc97fe9e07fae5563", size = 4952289 },
|
| 1478 |
+
{ url = "https://files.pythonhosted.org/packages/31/c0/b25d9528df296b9a3306ba21ff982fc5b698c45ab78b94d18c2d6ae71fd9/lxml-6.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bd5913b4972681ffc9718bc2d4c53cde39ef81415e1671ff93e9aa30b46595e7", size = 5111310 },
|
| 1479 |
+
{ url = "https://files.pythonhosted.org/packages/e9/af/681a8b3e4f668bea6e6514cbcb297beb6de2b641e70f09d3d78655f4f44c/lxml-6.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:390240baeb9f415a82eefc2e13285016f9c8b5ad71ec80574ae8fa9605093cd7", size = 5025457 },
|
| 1480 |
+
{ url = "https://files.pythonhosted.org/packages/69/f8/693b1a10a891197143c0673fcce5b75fc69132afa81a36e4568c12c8faba/lxml-6.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ca50bd612438258a91b5b3788c6621c1f05c8c478e7951899f492be42defc0da", size = 5257565 },
|
| 1481 |
+
{ url = "https://files.pythonhosted.org/packages/a8/96/e08ff98f2c6426c98c8964513c5dab8d6eb81dadcd0af6f0c538ada78d33/lxml-6.0.0-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:c24b8efd9c0f62bad0439283c2c795ef916c5a6b75f03c17799775c7ae3c0c9e", size = 4713390 },
|
| 1482 |
+
{ url = "https://files.pythonhosted.org/packages/a8/83/6184aba6cc94d7413959f6f8f54807dc318fdcd4985c347fe3ea6937f772/lxml-6.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:afd27d8629ae94c5d863e32ab0e1d5590371d296b87dae0a751fb22bf3685741", size = 5066103 },
|
| 1483 |
+
{ url = "https://files.pythonhosted.org/packages/ee/01/8bf1f4035852d0ff2e36a4d9aacdbcc57e93a6cd35a54e05fa984cdf73ab/lxml-6.0.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:54c4855eabd9fc29707d30141be99e5cd1102e7d2258d2892314cf4c110726c3", size = 4791428 },
|
| 1484 |
+
{ url = "https://files.pythonhosted.org/packages/5c/f7/5495829a864bc5f8b0798d2b52a807c89966523140f3d6fa3a58ab6720ea/lxml-6.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36531f81c8214e293097cd2b7873f178997dae33d3667caaae8bdfb9666b76c0", size = 5281290 },
|
| 1485 |
+
{ url = "https://files.pythonhosted.org/packages/79/56/6b8edb79d9ed294ccc4e881f4db1023af56ba451909b9ce79f2a2cd7c532/lxml-6.0.0-cp312-cp312-win32.whl", hash = "sha256:690b20e3388a7ec98e899fd54c924e50ba6693874aa65ef9cb53de7f7de9d64a", size = 3613495 },
|
| 1486 |
+
{ url = "https://files.pythonhosted.org/packages/0b/1e/cc32034b40ad6af80b6fd9b66301fc0f180f300002e5c3eb5a6110a93317/lxml-6.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:310b719b695b3dd442cdfbbe64936b2f2e231bb91d998e99e6f0daf991a3eba3", size = 4014711 },
|
| 1487 |
+
{ url = "https://files.pythonhosted.org/packages/55/10/dc8e5290ae4c94bdc1a4c55865be7e1f31dfd857a88b21cbba68b5fea61b/lxml-6.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:8cb26f51c82d77483cdcd2b4a53cda55bbee29b3c2f3ddeb47182a2a9064e4eb", size = 3674431 },
|
| 1488 |
+
{ url = "https://files.pythonhosted.org/packages/79/21/6e7c060822a3c954ff085e5e1b94b4a25757c06529eac91e550f3f5cd8b8/lxml-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6da7cd4f405fd7db56e51e96bff0865b9853ae70df0e6720624049da76bde2da", size = 8414372 },
|
| 1489 |
+
{ url = "https://files.pythonhosted.org/packages/a4/f6/051b1607a459db670fc3a244fa4f06f101a8adf86cda263d1a56b3a4f9d5/lxml-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b34339898bb556a2351a1830f88f751679f343eabf9cf05841c95b165152c9e7", size = 4593940 },
|
| 1490 |
+
{ url = "https://files.pythonhosted.org/packages/8e/74/dd595d92a40bda3c687d70d4487b2c7eff93fd63b568acd64fedd2ba00fe/lxml-6.0.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl", hash = "sha256:51a5e4c61a4541bd1cd3ba74766d0c9b6c12d6a1a4964ef60026832aac8e79b3", size = 5214329 },
|
| 1491 |
+
{ url = "https://files.pythonhosted.org/packages/52/46/3572761efc1bd45fcafb44a63b3b0feeb5b3f0066886821e94b0254f9253/lxml-6.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d18a25b19ca7307045581b18b3ec9ead2b1db5ccd8719c291f0cd0a5cec6cb81", size = 4947559 },
|
| 1492 |
+
{ url = "https://files.pythonhosted.org/packages/94/8a/5e40de920e67c4f2eef9151097deb9b52d86c95762d8ee238134aff2125d/lxml-6.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d4f0c66df4386b75d2ab1e20a489f30dc7fd9a06a896d64980541506086be1f1", size = 5102143 },
|
| 1493 |
+
{ url = "https://files.pythonhosted.org/packages/7c/4b/20555bdd75d57945bdabfbc45fdb1a36a1a0ff9eae4653e951b2b79c9209/lxml-6.0.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f4b481b6cc3a897adb4279216695150bbe7a44c03daba3c894f49d2037e0a24", size = 5021931 },
|
| 1494 |
+
{ url = "https://files.pythonhosted.org/packages/d4/dd/39c8507c16db6031f8c1ddf70ed95dbb0a6d466a40002a3522c128aba472/lxml-6.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae06fbab4f1bb7db4f7c8ca9897dc8db4447d1a2b9bee78474ad403437bcc29", size = 5247467 },
|
| 1495 |
+
{ url = "https://files.pythonhosted.org/packages/4d/56/732d49def0631ad633844cfb2664563c830173a98d5efd9b172e89a4800d/lxml-6.0.0-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:1fa377b827ca2023244a06554c6e7dc6828a10aaf74ca41965c5d8a4925aebb4", size = 4720601 },
|
| 1496 |
+
{ url = "https://files.pythonhosted.org/packages/8f/7f/6b956fab95fa73462bca25d1ea7fc8274ddf68fb8e60b78d56c03b65278e/lxml-6.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1676b56d48048a62ef77a250428d1f31f610763636e0784ba67a9740823988ca", size = 5060227 },
|
| 1497 |
+
{ url = "https://files.pythonhosted.org/packages/97/06/e851ac2924447e8b15a294855caf3d543424364a143c001014d22c8ca94c/lxml-6.0.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:0e32698462aacc5c1cf6bdfebc9c781821b7e74c79f13e5ffc8bfe27c42b1abf", size = 4790637 },
|
| 1498 |
+
{ url = "https://files.pythonhosted.org/packages/52/03/0e764ce00b95e008d76b99d432f1807f3574fb2945b496a17807a1645dbd/lxml-6.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7488a43033c958637b1a08cddc9188eb06d3ad36582cebc7d4815980b47e27ef", size = 5272430 },
|
| 1499 |
+
{ url = "https://files.pythonhosted.org/packages/5f/01/d48cc141bc47bc1644d20fe97bbd5e8afb30415ec94f146f2f76d0d9d098/lxml-6.0.0-cp313-cp313-win32.whl", hash = "sha256:5fcd7d3b1d8ecb91445bd71b9c88bdbeae528fefee4f379895becfc72298d181", size = 3612896 },
|
| 1500 |
+
{ url = "https://files.pythonhosted.org/packages/f4/87/6456b9541d186ee7d4cb53bf1b9a0d7f3b1068532676940fdd594ac90865/lxml-6.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:2f34687222b78fff795feeb799a7d44eca2477c3d9d3a46ce17d51a4f383e32e", size = 4013132 },
|
| 1501 |
+
{ url = "https://files.pythonhosted.org/packages/b7/42/85b3aa8f06ca0d24962f8100f001828e1f1f1a38c954c16e71154ed7d53a/lxml-6.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:21db1ec5525780fd07251636eb5f7acb84003e9382c72c18c542a87c416ade03", size = 3672642 },
|
| 1502 |
+
]
|
| 1503 |
+
|
| 1504 |
[[package]]
|
| 1505 |
name = "markdown-it-py"
|
| 1506 |
version = "3.0.0"
|
|
|
|
| 2451 |
{ url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 },
|
| 2452 |
]
|
| 2453 |
|
| 2454 |
+
[[package]]
|
| 2455 |
+
name = "pytrends"
|
| 2456 |
+
version = "4.9.2"
|
| 2457 |
+
source = { registry = "https://pypi.org/simple" }
|
| 2458 |
+
dependencies = [
|
| 2459 |
+
{ name = "lxml" },
|
| 2460 |
+
{ name = "pandas" },
|
| 2461 |
+
{ name = "requests" },
|
| 2462 |
+
]
|
| 2463 |
+
sdist = { url = "https://files.pythonhosted.org/packages/e9/65/a242fd8fbe98c11bd51f0b57d4752905396a99c42c91c3213c3f44e741c8/pytrends-4.9.2.tar.gz", hash = "sha256:691c6e36b1aeaa4754f3692bdbad0dff446e528ffb052eee2e7f139aaa2c6989", size = 247162 }
|
| 2464 |
+
wheels = [
|
| 2465 |
+
{ url = "https://files.pythonhosted.org/packages/68/ba/7a24a3723c790000faf880505ff1cc46f4d29f46dd353037938a070c4d23/pytrends-4.9.2-py3-none-any.whl", hash = "sha256:d7d0ee956be2f6e3e9fc09376c4615efb9347039d6d1f46e6f4326a5b7a14f67", size = 15352 },
|
| 2466 |
+
]
|
| 2467 |
+
|
| 2468 |
[[package]]
|
| 2469 |
name = "pytz"
|
| 2470 |
version = "2025.2"
|
|
|
|
| 3208 |
{ name = "pydantic-ai" },
|
| 3209 |
{ name = "pyrsm" },
|
| 3210 |
{ name = "python-dotenv" },
|
| 3211 |
+
{ name = "pytrends" },
|
| 3212 |
{ name = "requests" },
|
| 3213 |
]
|
| 3214 |
|
|
|
|
| 3227 |
{ name = "pydantic-ai", specifier = ">=0.3.5" },
|
| 3228 |
{ name = "pyrsm", specifier = ">=1.6.0" },
|
| 3229 |
{ name = "python-dotenv", specifier = ">=1.1.1" },
|
| 3230 |
+
{ name = "pytrends", specifier = ">=4.9.2" },
|
| 3231 |
{ name = "requests", specifier = ">=2.32.4" },
|
| 3232 |
]
|
| 3233 |
|
www/style.css
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#blog_result {
|
| 2 |
+
font-family: system-ui, sans-serif;
|
| 3 |
+
line-height: 1.6;
|
| 4 |
+
background-color: #fdfdfd;
|
| 5 |
+
border: 1px solid #ddd;
|
| 6 |
+
padding: 1.5rem;
|
| 7 |
+
margin-top: 1rem;
|
| 8 |
+
border-radius: 8px;
|
| 9 |
+
max-width: 800px;
|
| 10 |
+
white-space: normal;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
#blog_result h1,
|
| 14 |
+
#blog_result h2,
|
| 15 |
+
#blog_result h3 {
|
| 16 |
+
margin-top: 1.5em;
|
| 17 |
+
margin-bottom: 0.5em;
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
#blog_result p {
|
| 21 |
+
margin-bottom: 1em;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
#blog_result ul {
|
| 25 |
+
padding-left: 1.2rem;
|
| 26 |
+
}
|