为ASGI应用生成网站地图。
项目描述
asgi-sitemaps
网站地图生成器,用于ASGI应用。受Django的网站地图框架启发。
内容
特性
- 构建并组合网站地图部分,生成单个动态ASGI端点。
- 支持从多种来源(静态列表、(异步) ORM查询等)中提取网站地图项。
- 与任何ASGI框架兼容。
- 完全类型注解。
- 100%测试覆盖率。
安装
使用pip安装
$ pip install 'asgi-sitemaps==1.*'
asgi-sitemaps
需要 Python 3.7+。
快速入门
让我们为 "Hello, world!" 应用程序构建一个静态网站地图。网站地图将包含对主页端点 /
的单个URL条目。
以下是项目文件结构
.
└── server
├── __init__.py
├── app.py
└── sitemap.py
首先,通过继承 Sitemap
声明一个网站地图部分,然后将其包装在 SitemapApp
中
# server/sitemap.py
import asgi_sitemaps
class Sitemap(asgi_sitemaps.Sitemap):
def items(self):
return ["/"]
def location(self, item: str):
return item
def changefreq(self, item: str):
return "monthly"
sitemap = asgi_sitemaps.SitemapApp(Sitemap(), domain="example.io")
现在,将 sitemap
端点注册为ASGI应用的路线。例如,如果使用Starlette
# server/app.py
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette.routing import Route
from .sitemap import sitemap
async def home(request):
return PlainTextResponse("Hello, world!")
routes = [
Route("/", home),
Route("/sitemap.xml", sitemap),
]
app = Starlette(routes=routes)
使用 $ uvicorn server.app:app
运行应用程序,然后请求网站地图
curl http://localhost:8000/sitemap.xml
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://example.io/</loc>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
太棒了!
了解更多信息
- 请参阅 如何使用 以了解更高级的使用方法,包括将网站地图拆分为多个部分以及从数据库查询动态生成条目。
- 请参阅
站点地图
API 参考 以获取所有支持的站点地图选项。
如何使用
网站地图部分
您可以将多个站点地图类组合成一个单一的站点地图端点。这对于将站点地图分割成多个部分很有用,这些部分可能有不同的 items()
和/或站点地图属性。这样的部分可以是静态页面、博客文章、近期文章等。
要这样做,声明多个站点地图类,然后将它们作为列表传递给 SitemapApp
# server/sitemap.py
import asgi_sitemaps
class StaticSitemap(asgi_sitemaps.Sitemap):
...
class BlogSitemap(asgi_sitemaps.Sitemap):
...
sitemap = asgi_sitemaps.SitemapApp([StaticSitemap(), BlogSitemap()], domain="example.io")
在构建最终的 sitemap.xml
时,每个站点地图的条目将被连接。
从数据库查询动态生成
Sitemap.items()
支持消费任何异步可迭代对象。这意味着您可以轻松地将它与异步数据库客户端或 ORM 集成,以便 Sitemap.items()
获取并返回生成您站点地图所需的相关行。
以下是一个使用 Databases 的示例,假设您在 server/resources.py
中有一个 Database
实例
# server/sitemap.py
import asgi_sitemaps
from .resources import database
class Sitemap(asgi_sitemaps.Sitemap):
async def items(self):
query = "SELECT permalink, updated_at FROM articles;"
return await database.fetch_all(query)
def location(self, row: dict):
return row["permalink"]
高级Web框架集成
asgi-sitemaps
是框架无关的,您可以使用 Sitemap
实例上的 .scope
属性 将 ASGI 作用域馈送到您特定的框架 API 中,以检查和操作请求信息。
以下是一个使用 Starlette 的示例,其中我们构建静态页面的站点地图。为了从原始 URL 路径解耦,页面通过视图名称进行引用。我们通过从 ASGI .scope
构建一个 Request
实例并使用 .url_for()
来反向查找它们的 URL
# server/sitemap.py
import asgi_sitemaps
from starlette.datastructures import URL
from starlette.requests import Request
class StaticSitemap(asgi_sitemaps.Sitemap):
def items(self):
return ["home", "about", "blog:home"]
def location(self, name: str):
request = Request(scope=self.scope)
url = request.url_for(name)
return URL(url).path
相应的 Starlette 路由表可能看起来像这样
# server/routes.py
from starlette.routing import Mount, Route
from . import views
from .sitemap import sitemap
routes = [
Route("/", views.home, name="home"),
Route("/about", views.about, name="about"),
Route("/blog/", views.blog_home, name="blog:home"),
Route("/sitemap.xml", sitemap),
]
API参考
class Sitemap
表示站点地图条目的来源。
您可以指定 T
类型的站点地图项以获得额外的类型安全
import asgi_sitemaps
class MySitemap(asgi_sitemaps.Sitemap[str]):
...
async items
签名:async def () -> Union[Iterable[T], AsyncIterable[T]]
(必需) 返回相同类型的项目的一个或多个可迭代对象或异步可迭代对象。每个项目将被原样传递给 .location()
、.lastmod()
、.changefreq()
和 .priority()
。
示例
# Simplest usage: return a list
def items(self) -> List[str]:
return ["/", "/contact"]
# Async operations are also supported
async def items(self) -> List[dict]:
query = "SELECT permalink, updated_at FROM pages;"
return await database.fetch_all(query)
# Sync and async generators are also supported
async def items(self) -> AsyncIterator[dict]:
query = "SELECT permalink, updated_at FROM pages;"
async for row in database.aiter_rows(query):
yield row
location
签名:def (item: T) -> str
(必需) 返回站点地图项目的绝对路径。
"绝对路径"意味着没有协议或域的 URL 路径。例如:/blog/my-article
。(因此 https://mydomain.com/blog/my-article
不是有效的位置,mydomain.com/blog/my-article
也不是。)
lastmod
签名:def (item: T) -> Optional[datetime.datetime]
(可选) 返回站点地图项目的最后修改日期,作为 datetime
对象,或 None
(默认值)表示没有 lastmod
字段。
changefreq
签名:def (item: T) -> Optional[str]
(可选) 返回站点地图项目的更改频率。
可能的值有
None
- 无changefreq
字段(默认值)。"always"
"hourly"
"daily"
"weekly"
"monthly"
"yearly"
"never"
priority
签名:def (item: T) -> float
(可选) 返回站点地图项目的优先级。必须在 0 到 1 之间。默认值为 0.5
。
protocol
类型:str
(可选) 此属性定义用于构建站点地图 URL 的协议。
可能的值有
"auto"
- 请求站点地图时使用的协议(默认值)。"http"
"https"
scope
此属性返回当前 HTTP 请求的 ASGI 作用域。
class SitemapApp
一个响应HTTP请求并返回站点地图(sitemap.xml)内容的ASGI应用。
参数
- (必需)
sitemaps
- 一个Sitemap
对象或一个Sitemap
对象列表,用于生成站点地图条目。 - (必需)
domain
- 生成站点地图URL时使用的域名。
示例
sitemap = SitemapApp(Sitemap(), domain="mydomain.com")
sitemap = SitemapApp([StaticSitemap(), BlogSitemap()], domain="mydomain.com")
许可证
MIT
变更日志
此项目的所有重大变更都将记录在此文件中。
格式基于 Keep a Changelog。
1.0 - 2022-02-13
新增
- 现在标记为生产/稳定软件。 (Pull #14)
- 添加对Python 3.9和Python 3.10的官方支持。 (Pull #13)
0.3.2 - 2020-07-07
修复
- 修复对异步项的支持。 (Pull #9)
0.3.1 - 2020-07-05
修复
- 修复
Scope
类型提示:值现在是Any
。
0.3.0 - 2020-07-05
此版本将方法从“抓取ASGI应用以收集URL”更改为受Django的站点地图框架启发的基于类编程API。
因此,命令行应用不再存在。用户应定义 Sitemap
类,将它们组合到 SitemapApp
端点中,并将其添加到他们的ASGI应用路由表中。
有关更多信息,请参阅新的 README.md
文档。
变更
- 切换到基于类的动态端点API。 (Pull #4)
0.2.0 - 2020-06-01
变更
- 项目从
sitemaps
重命名为asgi-sitemaps
- ASGI应用的站点地图生成。 (Pull #2) - 修改CLI和编程API选项以适应新的“仅ASGI”项目范围。 (Pull #2)
- CLI现在从stdin读取(用于
--check
模式)并将站点地图输出到stdout。 (Pull #2)
删除
- 删除对爬取任意远程服务器的支持。 (Pull #2)
修复
- 不要将非200或非HTML URL包含在站点地图中。 (Pull #2)
0.1.0 - 2020-05-31
新增
- 初始实现:CLI和编程异步API。
项目详情
下载文件
下载您平台上的文件。如果您不确定要选择哪个,请了解更多关于 安装包 的信息。
源分发
构建分发
asgi-sitemaps-1.0.0.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 07d63459eb353990f5dc3cce8b49d4bca6f77db38c49b4d35e4ef84e881f4368 |
|
MD5 | 669c474cc34249d747bf6dd1da71c9fa |
|
BLAKE2b-256 | ba356a52cd37f7e9c9386755c1ec1bdd2b6faa3d44f22744841339e7508bd2bb |
asgi_sitemaps-1.0.0-py3-none-any.whl的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 9040d1a17abd72d800e2f9e567d7d7bdac0fe63858db4608c98bc4c39a895470 |
|
MD5 | 1cb51dc248d104cdbf3c49ec57c18a1f |
|
BLAKE2b-256 | 551cd2ec9fbd7d4ed7ec3e72a763c0b9944d9d6f70454234048c00c895c43540 |