跳转到主要内容

为ASGI应用生成网站地图。

项目描述

asgi-sitemaps

Build Status Coverage Python versions Package version

网站地图生成器,用于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 (12.4 kB 查看哈希)

上传时间

构建分发

asgi_sitemaps-1.0.0-py3-none-any.whl (9.3 kB 查看哈希)

上传时间 Python 3

支持者