mirror of
https://github.com/vinta/awesome-python.git
synced 2026-07-01 05:13:11 +00:00
Merge branch 'master' into fix/authlib-description
This commit is contained in:
commit
844f343b58
8 changed files with 257 additions and 39 deletions
20
README.md
20
README.md
|
|
@ -134,10 +134,10 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents
|
|||
|
||||
- Agent Skills
|
||||
- [django-ai-plugins](https://github.com/vintasoftware/django-ai-plugins) - Django backend agent skills for Django, DRF, Celery, and Django-specific code review.
|
||||
- [graphify](https://github.com/safishamsi/graphify) - Turn any folder of code, SQL schemas, R scripts, shell scripts, docs, papers, images, or videos into a queryable knowledge graph.
|
||||
- [graphify](https://github.com/safishamsi/graphify) - Turn any folder of code, SQL schemas, docs, papers, images, or videos into a queryable knowledge graph.
|
||||
- [nuwa-skill](https://github.com/alchaincyf/nuwa-skill/blob/main/README_EN.md) - Nuwa distills the thinking of anyone — let Musk, Naval, Munger, and Feynman work for you.
|
||||
- [sentry-skills](https://github.com/getsentry/skills) - Python-focused engineering skills for code review, debugging, and backend workflows.
|
||||
- [trailofbits-skills](https://github.com/trailofbits/skills) - Python-friendly security skills for auditing, testing, and safer backend development. Also [skills-curated](https://github.com/trailofbits/skills-curated).
|
||||
- [trailofbits-skills](https://github.com/trailofbits/skills) - Python-friendly security skills for auditing, testing, and safer backend development.
|
||||
- Orchestration
|
||||
- [ag2](https://github.com/ag2ai/ag2) - An open-source AgentOS for multi-agent orchestration and building agentic AI systems.
|
||||
- [autogen](https://github.com/microsoft/autogen) - A programming framework for building agentic AI applications.
|
||||
|
|
@ -148,6 +148,7 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents
|
|||
- [dspy](https://github.com/stanfordnlp/dspy) - A framework for programming, not prompting, language models.
|
||||
- [hermes-agent](https://github.com/nousresearch/hermes-agent) - An adaptive AI agent framework that grows with you.
|
||||
- [langchain](https://github.com/langchain-ai/langchain) - Building applications with LLMs through composability.
|
||||
- [langgraph](https://github.com/langchain-ai/langgraph) - Low-level orchestration framework for building stateful, long-running LLM agents.
|
||||
- [openai-agents](https://github.com/openai/openai-agents-python) - OpenAI's framework for building and managing AI agents.
|
||||
- [OpenChronicle](https://github.com/Einsia/OpenChronicle) - Open-source, local-first memory for any tool-capable LLM agent.
|
||||
- [promptise](https://github.com/promptise-com/foundry) - A framework for building end-to-end production-ready agentic systems, scalable & secure MCP's and autonomous agents.
|
||||
|
|
@ -157,8 +158,10 @@ _Libraries for building AI applications, LLM integrations, and autonomous agents
|
|||
- [instructor](https://github.com/567-labs/instructor) - A library for extracting structured data from LLMs, powered by Pydantic.
|
||||
- [llama-index](https://github.com/run-llama/llama_index) - A data framework for your LLM application.
|
||||
- [mem0](https://github.com/mem0ai/mem0) - An intelligent memory layer for AI agents enabling personalized interactions.
|
||||
- [outlines](https://github.com/dottxt-ai/outlines) - Structured text generation for LLMs with JSON schema, regex, and grammar-constrained decoding.
|
||||
- Pre-trained Models and Inference
|
||||
- [diffusers](https://github.com/huggingface/diffusers) - A library that provides pre-trained diffusion models for generating and editing images, audio, and video.
|
||||
- [LiteLLM](https://github.com/BerriAI/litellm) - Call 100+ LLMs using OpenAI format.
|
||||
- [mlx-lm](https://github.com/ml-explore/mlx-lm) - Run and fine-tune large language models on Apple Silicon with MLX.
|
||||
- [sglang](https://github.com/sgl-project/sglang) - A high-performance serving framework for large language models and multimodal models.
|
||||
- [transformers](https://github.com/huggingface/transformers) - A framework that lets you easily use pre-trained transformer models for NLP, vision, and audio tasks.
|
||||
|
|
@ -192,7 +195,7 @@ _Libraries for Machine Learning. Also see [awesome-machine-learning](https://git
|
|||
- [mindsdb](https://github.com/mindsdb/minds-platform) - MindsDB is an open source AI layer for existing databases that allows you to effortlessly develop, train and deploy state-of-the-art machine learning models using standard queries.
|
||||
- [pgmpy](https://github.com/pgmpy/pgmpy) - A Python library for probabilistic graphical models and Bayesian networks.
|
||||
- [scikit-learn](https://github.com/scikit-learn/scikit-learn) - The most popular Python library for Machine Learning with extensive documentation and community support.
|
||||
- * [scikit-lego](https://github.com/koaning/scikit-lego) - A collection of lego bricks for scikit-learn pipelines.
|
||||
- - [scikit-lego](https://github.com/koaning/scikit-lego) - A collection of lego bricks for scikit-learn pipelines.
|
||||
- [spark.ml](https://github.com/apache/spark) - [Apache Spark](https://spark.apache.org/)'s scalable [Machine Learning library](https://spark.apache.org/docs/latest/ml-guide.html) for distributed computing.
|
||||
- [TabGAN](https://github.com/Diyago/Tabular-data-generation) - Synthetic tabular data generation using GANs, Diffusion Models, and LLMs.
|
||||
- [timesfm](https://github.com/google-research/timesfm) - A pretrained foundation model from Google Research for time-series forecasting.
|
||||
|
|
@ -269,7 +272,7 @@ _Libraries for building RESTful and GraphQL APIs._
|
|||
- [connexion](https://github.com/spec-first/connexion) - A spec-first framework that automatically handles requests based on your OpenAPI specification.
|
||||
- [falcon](https://github.com/falconry/falcon) - A high-performance framework for building cloud APIs and web app backends.
|
||||
- [fastapi](https://github.com/fastapi/fastapi) - A modern, fast, web framework for building APIs with standard Python type hints.
|
||||
- [sanic](https://github.com/sanic-org/sanic) - A Python 3.6+ web server and web framework that's written to go fast.
|
||||
- [sanic](https://github.com/sanic-org/sanic) - A Python web server and web framework that's written to go fast.
|
||||
- [strawberry](https://github.com/strawberry-graphql/strawberry) - A GraphQL library that leverages Python type annotations for schema definition.
|
||||
- [webargs](https://github.com/marshmallow-code/webargs) - A friendly library for parsing HTTP request arguments with built-in support for popular web frameworks.
|
||||
|
||||
|
|
@ -326,7 +329,7 @@ _Libraries for implementing authentication schemes._
|
|||
- JWT
|
||||
- [pyjwt](https://github.com/jpadilla/pyjwt) - JSON Web Token implementation in Python.
|
||||
- Permissions
|
||||
- [django-guardian](https://github.com/django-guardian/django-guardian) - Implementation of per object permissions for Django 1.2+
|
||||
- [django-guardian](https://github.com/django-guardian/django-guardian) - Implementation of per-object permissions for Django.
|
||||
- [django-rules](https://github.com/dfunckt/django-rules) - A tiny but powerful app providing object-level permissions to Django, without requiring a database.
|
||||
|
||||
### Admin Panels
|
||||
|
|
@ -444,6 +447,7 @@ _Databases implemented in Python._
|
|||
- [pickledb](https://github.com/patx/pickledb) - A simple and lightweight key-value store for Python.
|
||||
- [tinydb](https://github.com/msiemens/tinydb) - A tiny, document-oriented database.
|
||||
- [ZODB](https://github.com/zopefoundation/ZODB) - A native object database for Python. A key-value and object graph database.
|
||||
- [zvec](https://github.com/alibaba/zvec) - An embedded vector database for on-device RAG and edge AI, the SQLite of vector databases.
|
||||
|
||||
### Caching
|
||||
|
||||
|
|
@ -531,7 +535,6 @@ _Libraries for visualizing data. Also see [awesome-javascript](https://github.co
|
|||
- Dashboards and Apps
|
||||
- [gradio](https://github.com/gradio-app/gradio) - Build and share machine learning apps, all in Python.
|
||||
- [streamlit](https://github.com/streamlit/streamlit) - A framework which lets you build dashboards, generate reports, or create chat apps in minutes.
|
||||
|
||||
### Geolocation
|
||||
|
||||
_Libraries for geocoding addresses and working with latitudes and longitudes._
|
||||
|
|
@ -852,6 +855,7 @@ _Libraries for working with graphical user interface applications._
|
|||
- [toga](https://github.com/beeware/toga) - A Python native, OS native GUI toolkit.
|
||||
- [wxPython](https://github.com/wxWidgets/Phoenix) - A blending of the wxWidgets C++ class library with the Python.
|
||||
- Web-based
|
||||
- [buridan/ui](https://github.com/LineIndent/ui) - Composable, themeable components designed for Reflex. Extend, override, and ship without fighting the framework. Open source.
|
||||
- [flet](https://github.com/flet-dev/flet) - Cross-platform GUI framework for building modern apps in pure Python.
|
||||
- [nicegui](https://github.com/zauberzeug/nicegui) - An easy-to-use, Python-based UI framework, which shows up in your web browser.
|
||||
- [pywebview](https://github.com/r0x0r/pywebview/) - A lightweight cross-platform native wrapper around a webview component.
|
||||
|
|
@ -869,7 +873,7 @@ _Libraries for parsing and manipulating plain texts._
|
|||
|
||||
- General
|
||||
- [babel](https://github.com/python-babel/babel) - An internationalization library for Python.
|
||||
- [chardet](https://github.com/chardet/chardet) - Python 2/3 compatible character encoding detector.
|
||||
- [chardet](https://github.com/chardet/chardet) - Python character encoding detector.
|
||||
- [difflib](https://docs.python.org/3/library/difflib.html) - (Python standard library) Helpers for computing deltas.
|
||||
- [ftfy](https://github.com/rspeer/python-ftfy) - Makes Unicode text less broken and more consistent automagically.
|
||||
- [pangu.py](https://github.com/vinta/pangu.py) - Paranoid text spacing.
|
||||
|
|
@ -882,6 +886,7 @@ _Libraries for parsing and manipulating plain texts._
|
|||
- [sqids](https://github.com/sqids/sqids-python) - A library for generating short unique IDs from numbers.
|
||||
- [shortuuid](https://github.com/skorokithakis/shortuuid) - A generator library for concise, unambiguous and URL-safe UUIDs.
|
||||
- Parser
|
||||
- [parsy](https://github.com/python-parsy/parsy) - Easy, generic parser combinator library for creating parsers.
|
||||
- [pygments](https://github.com/pygments/pygments) - A generic syntax highlighter.
|
||||
- [pyparsing](https://github.com/pyparsing/pyparsing) - A general purpose framework for generating parsers.
|
||||
- [python-nameparser](https://github.com/derek73/python-nameparser) - Parsing human names into their individual components.
|
||||
|
|
@ -1126,6 +1131,7 @@ _Libraries for application-layer web security._
|
|||
_Libraries for programming with hardware._
|
||||
|
||||
- [bleak](https://github.com/hbldh/bleak) - A cross platform Bluetooth Low Energy Client for Python using asyncio.
|
||||
- [jumpstarter](https://github.com/jumpstarter-dev/jumpstarter) - A hardware-in-the-loop testing framework with a Python client library for automated testing on real and virtual hardware.
|
||||
- [pynput](https://github.com/moses-palmer/pynput) - A library to control and monitor input devices.
|
||||
- [synology-api](https://github.com/N4S4/synology-api) - Python wrapper for Synology NAS APIs: Surveillance Station, File Station, Download Station, Docker, and 50+ other endpoints.
|
||||
|
||||
|
|
|
|||
|
|
@ -26,29 +26,37 @@ Your sponsorship puts your product in front of developers at the exact moment th
|
|||
- Large logo and one-line description (max 120 characters) pinned at the very top of the README, above all project entries
|
||||
- Logo link in the sponsor section of [awesome-python.com](https://awesome-python.com/)
|
||||
|
||||
### Featured Sponsor - $150/month
|
||||
### Featured Sponsor - $200/month
|
||||
|
||||
- Text entry (`[Name](URL) - Description.`, max 120 characters) pinned at the top of the README, directly below Headline sponsors
|
||||
- Text link in the sponsor section of [awesome-python.com](https://awesome-python.com/)
|
||||
|
||||
### Indie Dev Sponsor - $99/month or $249/quarter
|
||||
|
||||
- Lower-cost tier for indie developers, solo founders, and one-person companies only
|
||||
- Text entry (`[Name](URL) - Description.`, max 120 characters) in the README sponsor section, directly below Featured sponsors
|
||||
- Text link in the sponsor section of [awesome-python.com](https://awesome-python.com/)
|
||||
|
||||
Indie Dev Sponsor is available only to founder-led (one-person company) products. Funded startups, larger companies, and products with enterprise sales teams should use Featured or Headline Sponsor.
|
||||
|
||||
## Get Started
|
||||
|
||||
Email [sponsorship@awesome-python.com](mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship) with:
|
||||
|
||||
- **Tier:** Headline Sponsor ($500/mo), Featured Sponsor ($200/mo), or Indie Dev Sponsor ($99/mo or $249/quarter)
|
||||
- **Content:** Product name, URL, logo, and description (Headline tier) or `[Name](URL) - Description.` entry (Featured or Indie Dev tier)
|
||||
- **Duration:** 1, 3, 6 months, or longer
|
||||
- **Payment method:** US bank transfer (ACH/wire) or PayPal
|
||||
|
||||
One upfront payment per term. Setup takes less than 24 hours.
|
||||
|
||||
## Previously Sponsored By
|
||||
|
||||
- [Warp](https://www.warp.dev/) - The terminal for modern developers.
|
||||
- [pyr](https://pyrun.dev) - Zero-config Python project manager.
|
||||
|
||||
## Get Started
|
||||
|
||||
Email [sponsorship@awesome-python.com](mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship) with:
|
||||
|
||||
- **Tier:** Headline Sponsor ($500/mo) or Featured Sponsor ($150/mo)
|
||||
- **Content:** Product name, URL, logo, and description (Headline tier) or `[Name](URL) - Description.` entry (Featured tier)
|
||||
- **Duration:** 1, 3, 6 months, or longer
|
||||
- **Payment method:** US bank transfer (ACH/wire) or PayPal
|
||||
|
||||
One upfront payment per term. Setup takes less than 24 hours.
|
||||
|
||||
## Editorial Independence
|
||||
|
||||
Sponsorship is logo/link placement in the README header. It does not influence which projects are listed. Listings are curated on merit through the normal [contribution process](CONTRIBUTING.md).
|
||||
Sponsorship is logo or link placement in the README header. It does not influence which projects are listed. Listings are curated on merit through the normal [contribution process](CONTRIBUTING.md).
|
||||
|
||||
We reserve the right to request changes to sponsor text, logos, or links that are misleading, off-topic, or incompatible with the README formatting.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ BUILTIN_PUBLIC_URL = f"{SITE_URL}categories/{BUILTIN_SLUG}/"
|
|||
|
||||
SPONSORSHIP_PATH = "/sponsorship/"
|
||||
SPONSORSHIP_PUBLIC_URL = f"{SITE_URL}sponsorship/"
|
||||
SPONSORSHIP_DESCRIPTION = "Sponsorship for awesome-python: tiers, audience, and how to get your product in front of professional Python developers evaluating tools for production use."
|
||||
|
||||
SOURCE_TYPE_DOMAINS = {
|
||||
"docs.python.org": "Built-in",
|
||||
|
|
@ -128,6 +129,8 @@ def _website_node() -> dict:
|
|||
"@id": WEBSITE_ID,
|
||||
"name": "Awesome Python",
|
||||
"url": SITE_URL,
|
||||
"inLanguage": "en",
|
||||
"sameAs": "https://github.com/vinta/awesome-python",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -164,21 +167,59 @@ def build_homepage_json_ld(entries: Sequence[TemplateEntry], total_categories: i
|
|||
"url": SITE_URL,
|
||||
"description": description,
|
||||
"isPartOf": ISPARTOF_WEBSITE,
|
||||
"inLanguage": "en",
|
||||
"mainEntity": _item_list_payload(entries),
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def category_meta_description(name: str, entry_count: int, description: str) -> str:
|
||||
count_sentence = f"Explore {entry_count} curated Python projects in {name}."
|
||||
def category_meta_title(name: str, parent_name: str | None = None) -> str:
|
||||
if parent_name:
|
||||
title = f"{name} for {parent_name} - Awesome Python"
|
||||
if len(title) <= 60:
|
||||
return title
|
||||
title = f"{parent_name}: {name} - Awesome Python"
|
||||
if len(title) <= 60:
|
||||
return title
|
||||
return f"{name} - Awesome Python"
|
||||
title = f"{name} Python Libraries - Awesome Python"
|
||||
if len(title) <= 60:
|
||||
return title
|
||||
return f"{name} - Awesome Python"
|
||||
|
||||
|
||||
def category_meta_description(name: str, entry_count: int, description: str, parent_name: str | None = None) -> str:
|
||||
target = f"{name} for {parent_name}" if parent_name else name
|
||||
count_sentence = f"Explore {entry_count} curated Python projects in {target}."
|
||||
if description:
|
||||
lead = description if description.endswith((".", "!", "?")) else f"{description}."
|
||||
return f"{lead} {count_sentence}"
|
||||
return f"{count_sentence} Part of the Awesome Python catalog."
|
||||
|
||||
|
||||
def build_category_json_ld(name: str, url: str, description: str, entries: Sequence[TemplateEntry]) -> dict:
|
||||
def build_breadcrumb_json_ld(items: Sequence[tuple[str, str]]) -> dict:
|
||||
return {
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": i,
|
||||
"name": name,
|
||||
"item": url,
|
||||
}
|
||||
for i, (name, url) in enumerate(items, start=1)
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_category_json_ld(
|
||||
name: str,
|
||||
url: str,
|
||||
description: str,
|
||||
entries: Sequence[TemplateEntry],
|
||||
breadcrumbs: Sequence[tuple[str, str]],
|
||||
) -> dict:
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
|
|
@ -186,12 +227,38 @@ def build_category_json_ld(name: str, url: str, description: str, entries: Seque
|
|||
{
|
||||
"@type": "CollectionPage",
|
||||
"@id": url,
|
||||
"name": f"{name} Python Libraries",
|
||||
"name": name,
|
||||
"url": url,
|
||||
"description": description,
|
||||
"isPartOf": ISPARTOF_WEBSITE,
|
||||
"inLanguage": "en",
|
||||
"mainEntity": _item_list_payload(entries),
|
||||
},
|
||||
build_breadcrumb_json_ld(breadcrumbs),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_sponsorship_json_ld() -> dict:
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@graph": [
|
||||
_website_node(),
|
||||
{
|
||||
"@type": "WebPage",
|
||||
"@id": SPONSORSHIP_PUBLIC_URL,
|
||||
"name": "Sponsor Awesome Python",
|
||||
"url": SPONSORSHIP_PUBLIC_URL,
|
||||
"description": SPONSORSHIP_DESCRIPTION,
|
||||
"isPartOf": ISPARTOF_WEBSITE,
|
||||
"inLanguage": "en",
|
||||
},
|
||||
build_breadcrumb_json_ld(
|
||||
[
|
||||
("Awesome Python", SITE_URL),
|
||||
("Sponsorship", SPONSORSHIP_PUBLIC_URL),
|
||||
]
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
|
|
@ -548,14 +615,21 @@ def build(repo_root: Path) -> None:
|
|||
group_categories: Sequence[ParsedSection] | None = None,
|
||||
) -> None:
|
||||
page_dir.mkdir(parents=True, exist_ok=True)
|
||||
category_description = category_meta_description(category["name"], len(entries), category["description"])
|
||||
parent_name = parent_category["name"] if parent_category else None
|
||||
category_title = category_meta_title(category["name"], parent_name)
|
||||
category_description = category_meta_description(category["name"], len(entries), category["description"], parent_name)
|
||||
breadcrumbs = [("Awesome Python", SITE_URL)]
|
||||
if parent_category:
|
||||
breadcrumbs.append((parent_category["name"], category_public_url(parent_category)))
|
||||
breadcrumbs.append((category["name"], category_url))
|
||||
category_json_ld = json.dumps(
|
||||
build_category_json_ld(category["name"], category_url, category_description, entries),
|
||||
build_category_json_ld(category_title.removesuffix(" - Awesome Python"), category_url, category_description, entries, breadcrumbs),
|
||||
ensure_ascii=False,
|
||||
).replace("</", "<\\/")
|
||||
(page_dir / "index.html").write_text(
|
||||
tpl_category.render(
|
||||
category=category,
|
||||
category_title=category_title,
|
||||
category_url=category_url,
|
||||
category_description=category_description,
|
||||
entries=entries,
|
||||
|
|
@ -607,7 +681,11 @@ def build(repo_root: Path) -> None:
|
|||
hero_stats.append(f"{repo_stars}+ stars on GitHub")
|
||||
hero_stats.append(f"Updated {build_date.strftime('%B %d, %Y')}")
|
||||
(sponsorship_dir / "index.html").write_text(
|
||||
tpl_sponsorship.render(hero_stats=hero_stats),
|
||||
tpl_sponsorship.render(
|
||||
hero_stats=hero_stats,
|
||||
sponsorship_description=SPONSORSHIP_DESCRIPTION,
|
||||
sponsorship_json_ld=json.dumps(build_sponsorship_json_ld(), ensure_ascii=False).replace("</", "<\\/"),
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,9 @@ kbd {
|
|||
|
||||
.hero-topbar-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
|
|
@ -1278,7 +1280,7 @@ th[data-sort].sort-asc::after {
|
|||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: clamp(1.5rem, 3vw, 2.75rem);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ category.name }} Python Libraries - Awesome Python{% endblock %}
|
||||
{% block title %}{{ category_title }}{% endblock %}
|
||||
{% block description %}{{ category_description }}{% endblock %}
|
||||
{% block canonical_url %}{{ category_url }}{% endblock %}
|
||||
{% block alternate_links %}{% endblock %}
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
rel="noopener"
|
||||
>Submit a project</a
|
||||
>
|
||||
<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
rel="noopener"
|
||||
>Submit a project</a
|
||||
>
|
||||
<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Sponsor Awesome Python{% endblock %}
|
||||
{% block description %}Sponsorship for awesome-python: tiers, audience, and how to get your product in front of professional Python developers evaluating tools for production use.{% endblock %}
|
||||
{% block description %}{{ sponsorship_description }}{% endblock %}
|
||||
{% block canonical_url %}https://awesome-python.com/sponsorship/{% endblock %}
|
||||
{% block alternate_links %}{% endblock %}
|
||||
{% block extra_head %}
|
||||
<script type="application/ld+json">{{ sponsorship_json_ld | safe }}</script>
|
||||
{% endblock %}
|
||||
{% block header %}
|
||||
<header class="category-hero sponsorship-hero">
|
||||
<div class="hero-sheen" aria-hidden="true"></div>
|
||||
|
|
@ -19,6 +22,7 @@
|
|||
rel="noopener"
|
||||
>Submit a project</a
|
||||
>
|
||||
<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
|
|
@ -45,7 +49,7 @@
|
|||
>Email sponsorship@awesome-python.com</a
|
||||
>
|
||||
<a
|
||||
href="https://github.com/vinta/awesome-python"
|
||||
href="https://github.com/vinta/awesome-python/blob/master/SPONSORSHIP.md"
|
||||
class="hero-action hero-action-secondary"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
|
|
@ -71,8 +75,8 @@
|
|||
<div>
|
||||
<dt>Who visits</dt>
|
||||
<dd>
|
||||
Mid to senior Python developers arriving with a specific question:
|
||||
a maintained ORM, a fast HTTP client, a task queue worth running in
|
||||
Mid to senior Python developers arriving with a specific question: a
|
||||
maintained ORM, a fast HTTP client, a task queue worth running in
|
||||
production.
|
||||
</dd>
|
||||
</div>
|
||||
|
|
@ -123,7 +127,7 @@
|
|||
<li>Logo link in the sponsor section of awesome-python.com.</li>
|
||||
</ul>
|
||||
<a
|
||||
href="mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship%20-%20Headline"
|
||||
href="mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship%20-%20Headline%20Tier"
|
||||
class="tier-cta"
|
||||
>Email about Headline tier</a
|
||||
>
|
||||
|
|
@ -131,7 +135,7 @@
|
|||
<li class="tier">
|
||||
<p class="tier-eyebrow">Featured Sponsor</p>
|
||||
<p class="tier-price">
|
||||
<span class="tier-amount">$150</span>
|
||||
<span class="tier-amount">$200</span>
|
||||
<span class="tier-cadence">/ month</span>
|
||||
</p>
|
||||
<p class="tier-summary">
|
||||
|
|
@ -146,11 +150,40 @@
|
|||
<li>Text link in the sponsor section of awesome-python.com.</li>
|
||||
</ul>
|
||||
<a
|
||||
href="mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship%20-%20Featured"
|
||||
href="mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship%20-%20Featured%20Tier"
|
||||
class="tier-cta"
|
||||
>Email about Featured tier</a
|
||||
>
|
||||
</li>
|
||||
<li class="tier">
|
||||
<p class="tier-eyebrow">Indie Dev Sponsor</p>
|
||||
<p class="tier-price">
|
||||
<span class="tier-amount">$99</span>
|
||||
<span class="tier-cadence">/ month or $249 / quarter</span>
|
||||
</p>
|
||||
<p class="tier-summary">
|
||||
Lower-cost text link for eligible indie developers and solo
|
||||
founders.
|
||||
</p>
|
||||
<ul class="tier-includes">
|
||||
<li>
|
||||
Text entry (<code>[Name](URL) - Description.</code>, max 120
|
||||
characters) in the README sponsor section, directly below Featured
|
||||
sponsors.
|
||||
</li>
|
||||
<li>Text link in the sponsor section of awesome-python.com.</li>
|
||||
<li>
|
||||
Available only to founder-led, one-person-company products. Funded
|
||||
startups, agencies, recruiters, larger companies, and products
|
||||
with enterprise sales teams should use Featured or Headline.
|
||||
</li>
|
||||
</ul>
|
||||
<a
|
||||
href="mailto:sponsorship@awesome-python.com?subject=Awesome%20Python%20Sponsorship%20-%20Indie%20Dev%20Tier"
|
||||
class="tier-cta"
|
||||
>Email about Indie Dev tier</a
|
||||
>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -171,6 +204,12 @@
|
|||
>The terminal for modern developers.</span
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://pyrun.dev" target="_blank" rel="noopener">pyr</a>
|
||||
<span class="past-sponsor-desc"
|
||||
>Zero-config Python project manager.</span
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -193,13 +232,17 @@
|
|||
<dl class="sponsorship-facts">
|
||||
<div>
|
||||
<dt>Tier</dt>
|
||||
<dd>Headline Sponsor ($500/mo) or Featured Sponsor ($150/mo).</dd>
|
||||
<dd>
|
||||
Headline Sponsor ($500/mo), Featured Sponsor ($200/mo), or Indie Dev
|
||||
Sponsor ($99/mo or $249/quarter).
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Content</dt>
|
||||
<dd>
|
||||
Product name, URL, logo, and description (Headline tier), or
|
||||
<code>[Name](URL) - Description.</code> entry (Featured tier).
|
||||
<code>[Name](URL) - Description.</code> entry (Featured or Indie Dev
|
||||
tier).
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ class TestBuild:
|
|||
assert parser.links_by_rel["canonical"] == "https://awesome-python.com/categories/widgets/"
|
||||
assert parser.meta_by_property["og:url"] == "https://awesome-python.com/categories/widgets/"
|
||||
assert '<link rel="alternate" type="text/plain" href="/llms.txt" title="LLMs text entry point" />' not in category_html
|
||||
assert '<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>' in category_html
|
||||
assert "<h1>Widgets</h1>" in category_html
|
||||
assert 'Widget libraries. Also see <a href="https://example.com/widgets" target="_blank" rel="noopener">awesome-widgets</a>.' in category_html
|
||||
assert 'href="https://example.com/w1"' in category_html
|
||||
|
|
@ -481,6 +482,7 @@ class TestBuild:
|
|||
assert parser.meta_by_name["twitter:description"] == expected_description
|
||||
assert parser.meta_by_name["twitter:image"] == expected_image
|
||||
assert "<head>\n <meta charset" in html
|
||||
assert '<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>' in html
|
||||
assert 'id="hero-category-heading">Browse by category</h2>' in html
|
||||
assert 'class="hero-category-link" href="/categories/ai-and-agents/"' in html
|
||||
|
||||
|
|
@ -569,7 +571,7 @@ class TestBuild:
|
|||
|
||||
assert data["@context"] == "https://schema.org"
|
||||
graph = {node["@type"]: node for node in data["@graph"]}
|
||||
assert set(graph) == {"WebSite", "CollectionPage"}
|
||||
assert set(graph) == {"WebSite", "CollectionPage", "BreadcrumbList"}
|
||||
assert graph["WebSite"]["@id"] == "https://awesome-python.com/#website"
|
||||
collection = graph["CollectionPage"]
|
||||
assert collection["name"] == "Widgets Python Libraries"
|
||||
|
|
@ -588,6 +590,12 @@ class TestBuild:
|
|||
positions = sorted(item["position"] for item in item_list["itemListElement"])
|
||||
assert positions == [1, 2]
|
||||
|
||||
breadcrumbs = graph["BreadcrumbList"]["itemListElement"]
|
||||
assert breadcrumbs == [
|
||||
{"@type": "ListItem", "position": 1, "name": "Awesome Python", "item": "https://awesome-python.com/"},
|
||||
{"@type": "ListItem", "position": 2, "name": "Widgets", "item": "https://awesome-python.com/categories/widgets/"},
|
||||
]
|
||||
|
||||
def test_group_page_falls_back_to_default_description_in_json_ld(self, tmp_path):
|
||||
readme = textwrap.dedent("""\
|
||||
# T
|
||||
|
|
@ -685,9 +693,80 @@ class TestBuild:
|
|||
assert "<h1>Synchronous</h1>" in sync
|
||||
assert "category-breadcrumb" in sync
|
||||
|
||||
parser = HeadMetadataParser()
|
||||
parser.feed(sync)
|
||||
assert parser.title.strip() == "Synchronous for Web Frameworks - Awesome Python"
|
||||
assert parser.meta_by_name["description"] == "Explore 1 curated Python projects in Synchronous for Web Frameworks. Part of the Awesome Python catalog."
|
||||
|
||||
marker = '<script type="application/ld+json">'
|
||||
start = sync.index(marker) + len(marker)
|
||||
end = sync.index("</script>", start)
|
||||
graph = {node["@type"]: node for node in json.loads(sync[start:end])["@graph"]}
|
||||
assert graph["CollectionPage"]["name"] == "Synchronous for Web Frameworks"
|
||||
assert graph["BreadcrumbList"]["itemListElement"] == [
|
||||
{"@type": "ListItem", "position": 1, "name": "Awesome Python", "item": "https://awesome-python.com/"},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "Web Frameworks",
|
||||
"item": "https://awesome-python.com/categories/web-frameworks/",
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 3,
|
||||
"name": "Synchronous",
|
||||
"item": "https://awesome-python.com/categories/web-frameworks/synchronous/",
|
||||
},
|
||||
]
|
||||
|
||||
parent = (site / "categories" / "web-frameworks" / "index.html").read_text(encoding="utf-8")
|
||||
assert "category-breadcrumb" not in parent
|
||||
|
||||
def test_sponsorship_page_contains_json_ld(self, tmp_path):
|
||||
readme = textwrap.dedent("""\
|
||||
# T
|
||||
|
||||
## Projects
|
||||
|
||||
**Tools**
|
||||
|
||||
## Widgets
|
||||
|
||||
- [w1](https://example.com/w1) - A widget.
|
||||
|
||||
# Contributing
|
||||
|
||||
Done.
|
||||
""")
|
||||
self._copy_real_templates(tmp_path)
|
||||
(tmp_path / "README.md").write_text(readme, encoding="utf-8")
|
||||
build(tmp_path)
|
||||
|
||||
site = tmp_path / "website" / "output"
|
||||
html = (site / "sponsorship" / "index.html").read_text(encoding="utf-8")
|
||||
parser = HeadMetadataParser()
|
||||
parser.feed(html)
|
||||
|
||||
assert parser.title.strip() == "Sponsor Awesome Python"
|
||||
assert parser.meta_by_name["description"] == (
|
||||
"Sponsorship for awesome-python: tiers, audience, and how to get your product in front of professional Python developers evaluating tools for production use."
|
||||
)
|
||||
assert parser.links_by_rel["canonical"] == "https://awesome-python.com/sponsorship/"
|
||||
assert '<a href="/sponsorship/" class="hero-topbar-link">Sponsorship</a>' in html
|
||||
|
||||
marker = '<script type="application/ld+json">'
|
||||
start = html.index(marker) + len(marker)
|
||||
end = html.index("</script>", start)
|
||||
graph = {node["@type"]: node for node in json.loads(html[start:end])["@graph"]}
|
||||
|
||||
assert set(graph) == {"WebSite", "WebPage", "BreadcrumbList"}
|
||||
assert graph["WebPage"]["@id"] == "https://awesome-python.com/sponsorship/"
|
||||
assert graph["WebPage"]["url"] == "https://awesome-python.com/sponsorship/"
|
||||
assert graph["BreadcrumbList"]["itemListElement"] == [
|
||||
{"@type": "ListItem", "position": 1, "name": "Awesome Python", "item": "https://awesome-python.com/"},
|
||||
{"@type": "ListItem", "position": 2, "name": "Sponsorship", "item": "https://awesome-python.com/sponsorship/"},
|
||||
]
|
||||
|
||||
def test_index_embeds_filter_urls_json(self, tmp_path):
|
||||
readme = textwrap.dedent("""\
|
||||
# T
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue