]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
♻️ Refactor how sponsors data is handled for banners (#15852)
authorSebastián Ramírez <tiangolo@gmail.com>
Sat, 27 Jun 2026 12:47:35 +0000 (14:47 +0200)
committerGitHub <noreply@github.com>
Sat, 27 Jun 2026 12:47:35 +0000 (12:47 +0000)
.pre-commit-config.yaml
docs/en/data/sponsors.yml
docs/en/overrides/main.html
docs/en/overrides/partials/banner-sponsors.html [new file with mode: 0644]
scripts/docs.py

index 22f8971e672976c674e4044137872ec187a539c3..eb0762df500a4499578724145a4223e76f5ae68c 100644 (file)
@@ -65,6 +65,13 @@ repos:
         files: ^docs/en/docs/index\.md|docs/en/data/sponsors\.yml|scripts/docs\.py$
         pass_filenames: false
 
+      - id: render-banner-sponsors
+        language: unsupported
+        name: render sponsor banner partial
+        entry: uv run ./scripts/docs.py render-banner-sponsors
+        files: ^docs/en/data/sponsors\.yml|^docs/en/overrides/partials/banner-sponsors\.html|^scripts/docs\.py$
+        pass_filenames: false
+
       - id: update-languages
         language: unsupported
         name: update languages
index 3d011ba12c5dc8a8b8940af989a14ac7888f41d9..f9d4505f1de2def530393f7251b4a73c3404e702 100644 (file)
@@ -6,27 +6,38 @@ gold:
   - url: https://blockbee.io?ref=fastapi
     title: BlockBee Cryptocurrency Payment Gateway
     img: /img/sponsors/blockbee.png
+    banner_img: /img/sponsors/blockbee-banner.png
   - url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge
     title: Auth, user management and more for your B2B product
     img: /img/sponsors/propelauth.png
+    banner_url: https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=topbanner
+    banner_img: /img/sponsors/propelauth-banner.png
   - url: https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi
     title: Deploy & scale any full-stack web app on Render. Focus on building apps, not infra.
     img: /img/sponsors/render.svg
+    banner_img: /img/sponsors/render-banner.svg
   - url: https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi
     title: Cut Code Review Time & Bugs in Half with CodeRabbit
     img: /img/sponsors/coderabbit.png
+    banner_url: https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=banner&utm_campaign=fastapi
+    banner_img: /img/sponsors/coderabbit-banner.png
   - url: https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source
     title: The Gold Standard in Retail Account Linking
     img: /img/sponsors/subtotal.svg
+    banner_title: Making Retail Purchases Actionable for Brands and Developers
+    banner_img: /img/sponsors/subtotal-banner.svg
   - url: https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi
     title: Deploy enterprise applications at startup speed
     img: /img/sponsors/railway.png
+    banner_img: /img/sponsors/railway-banner.png
   - url: https://serpapi.com/?utm_source=fastapi_website
     title: "SerpApi: Web Search API"
     img: /img/sponsors/serpapi.png
+    banner_img: /img/sponsors/serpapi-banner.png
   - url: https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page
     title: "Greptile: The AI Code Reviewer"
     img: /img/sponsors/greptile.png
+    banner_img: /img/sponsors/greptile-banner.png
 silver:
   - url: https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display
     title: Pay as you go for market data
index 4b0e8111188f44fc31344765f033ebdff5b7c483..1905a65738f826300552b00715bbdc7099af24d3 100644 (file)
     </div>
   </div>
   <div id="announce-right" style="position: relative;">
-    <div class="item">
-      <a title="BlockBee Cryptocurrency Payment Gateway" style="display: block; position: relative;" href="https://blockbee.io?ref=fastapi" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/blockbee-banner.png" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Auth, user management and more for your B2B product" style="display: block; position: relative;" href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=topbanner" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/propelauth-banner.png" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra." style="display: block; position: relative;" href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/render-banner.svg" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Cut Code Review Time & Bugs in Half with CodeRabbit" style="display: block; position: relative;" href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=banner&utm_campaign=fastapi" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/coderabbit-banner.png" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Making Retail Purchases Actionable for Brands and Developers" style="display: block; position: relative;" href="https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/subtotal-banner.svg" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Deploy enterprise applications at startup speed" style="display: block; position: relative;" href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/railway-banner.png" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="SerpApi: Web Search API" style="display: block; position: relative;" href="https://serpapi.com/?utm_source=fastapi_website" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/serpapi-banner.png" />
-      </a>
-    </div>
-    <div class="item">
-      <a title="Greptile: The AI Code Reviewer" style="display: block; position: relative;" href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank">
-        <span class="sponsor-badge">sponsor</span>
-        <img class="sponsor-image" src="/img/sponsors/greptile-banner.png" />
-      </a>
-    </div>
+    {% include "partials/banner-sponsors.html" %}
   </div>
 </div>
 {% endblock %}
diff --git a/docs/en/overrides/partials/banner-sponsors.html b/docs/en/overrides/partials/banner-sponsors.html
new file mode 100644 (file)
index 0000000..ae689ad
--- /dev/null
@@ -0,0 +1,48 @@
+<div class="item">
+  <a title="BlockBee Cryptocurrency Payment Gateway" style="display: block; position: relative;" href="https://blockbee.io?ref=fastapi" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/blockbee-banner.png" alt="BlockBee Cryptocurrency Payment Gateway" />
+  </a>
+</div>
+<div class="item">
+  <a title="Auth, user management and more for your B2B product" style="display: block; position: relative;" href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=topbanner" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/propelauth-banner.png" alt="Auth, user management and more for your B2B product" />
+  </a>
+</div>
+<div class="item">
+  <a title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra." style="display: block; position: relative;" href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/render-banner.svg" alt="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra." />
+  </a>
+</div>
+<div class="item">
+  <a title="Cut Code Review Time & Bugs in Half with CodeRabbit" style="display: block; position: relative;" href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=banner&utm_campaign=fastapi" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/coderabbit-banner.png" alt="Cut Code Review Time & Bugs in Half with CodeRabbit" />
+  </a>
+</div>
+<div class="item">
+  <a title="Making Retail Purchases Actionable for Brands and Developers" style="display: block; position: relative;" href="https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/subtotal-banner.svg" alt="Making Retail Purchases Actionable for Brands and Developers" />
+  </a>
+</div>
+<div class="item">
+  <a title="Deploy enterprise applications at startup speed" style="display: block; position: relative;" href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/railway-banner.png" alt="Deploy enterprise applications at startup speed" />
+  </a>
+</div>
+<div class="item">
+  <a title="SerpApi: Web Search API" style="display: block; position: relative;" href="https://serpapi.com/?utm_source=fastapi_website" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/serpapi-banner.png" alt="SerpApi: Web Search API" />
+  </a>
+</div>
+<div class="item">
+  <a title="Greptile: The AI Code Reviewer" style="display: block; position: relative;" href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="/img/sponsors/greptile-banner.png" alt="Greptile: The AI Code Reviewer" />
+  </a>
+</div>
index 8e3d5e8327a7a2175f963308ad792f6e3f372b91..a108c8ddf8a35adcaa6d4d34ab05d194fdf52910 100644 (file)
@@ -249,6 +249,7 @@ def stage_zensical_docs(lang: str) -> Path:
                     encoding="utf-8",
                 )
 
+    render_banner_sponsors()
     shutil.copytree(en_docs_path / "data", lang_stage_path / "data")
     shutil.copytree(en_docs_path / "overrides", lang_stage_path / "overrides")
 
@@ -461,6 +462,7 @@ def live() -> None:
     """
     Serve the English docs with livereload from the source files.
     """
+    render_banner_sponsors()
     subprocess.run(
         [
             "zensical",
@@ -508,6 +510,56 @@ def get_updated_config_content() -> dict[str, Any]:
     return config
 
 
+banner_sponsors_template = """{% for sponsor in banner_sponsors -%}
+<div class="item">
+  <a title="{{ sponsor.title }}" style="display: block; position: relative;" href="{{ sponsor.url }}" target="_blank">
+    <span class="sponsor-badge">sponsor</span>
+    <img class="sponsor-image" src="{{ sponsor.img }}" alt="{{ sponsor.title }}" />
+  </a>
+</div>
+{% endfor %}
+"""
+
+
+def get_banner_sponsors(sponsors: dict[str, Any]) -> list[dict[str, str]]:
+    banner_sponsors: list[dict[str, str]] = []
+    for sponsor in sponsors.get("gold", []):
+        banner_img = sponsor.get("banner_img")
+        if not banner_img:
+            continue
+        banner_sponsors.append(
+            {
+                "url": sponsor.get("banner_url", sponsor["url"]),
+                "title": sponsor.get("banner_title", sponsor["title"]),
+                "img": banner_img,
+            }
+        )
+    return banner_sponsors
+
+
+def render_banner_sponsors_partial() -> str:
+    sponsors_path = en_docs_path / "data" / "sponsors.yml"
+    sponsors = yaml.safe_load(sponsors_path.read_text(encoding="utf-8"))
+    template = Template(banner_sponsors_template)
+    return template.render(banner_sponsors=get_banner_sponsors(sponsors))
+
+
+@app.command()
+def render_banner_sponsors() -> None:
+    """
+    Render the sponsor banner partial from sponsors.yml.
+    """
+    partial_path = en_docs_path / "overrides" / "partials" / "banner-sponsors.html"
+    old_content = partial_path.read_text("utf-8") if partial_path.is_file() else ""
+    new_content = render_banner_sponsors_partial()
+    if new_content != old_content:
+        print(f"{partial_path} outdated from the latest sponsors.yml")
+        print(f"Updating {partial_path}")
+        partial_path.write_text(new_content, encoding="utf-8")
+        raise typer.Exit(1)
+    print(f"{partial_path} is up to date ✅")
+
+
 @app.command()
 def ensure_non_translated() -> None:
     """