Skip to main content

bsqb

CI PyPI version Python versions License: MIT Sponsor

bsqb (Brave Search Query Builder) is a type-safe, zero-dependency Python library for constructing Brave Search query strings using the official search operators.

It helps you build valid q parameters for the Brave Search API with a fluent API, automatic quoting, and validation against API limits.

Features

  • Complete operator coverage — All operators from the official Brave Search documentation
  • Fluent API — Chain methods for readable, composable queries
  • Type-safe — Full type hints and py.typed marker for mypy/Pylance
  • Zero dependencies — Lightweight core with no runtime requirements
  • API limit validation — Enforces the 400 character / 50 word limits on q
  • Logical operators — AND, OR, NOT with Python operators (&, |, ~)

Installation

pip install bsqb

Quick start

from bsqb import Query

# Basic query with field operators
query = Query("machine learning").filetype("pdf").lang("en")
print(query.build())
# machine learning filetype:pdf lang:en

# Use with the Brave Search API
import urllib.parse
import urllib.request

params = urllib.parse.urlencode({"q": query.build()})
url = f"https://api.search.brave.com/res/v1/web/search?{params}"
request = urllib.request.Request(
    url,
    headers={"X-Subscription-Token": "YOUR_API_KEY"},
)

Supported operators

Operator Method Example output
Plain term Query("term") term
Exact phrase .phrase("exact phrase") "exact phrase"
Force include .include("term") +term
Exclude .exclude("term") -term
File extension .ext("pdf") ext:pdf
File type .filetype("pdf") filetype:pdf
In title .intitle("2023") intitle:2023
In body .inbody("keyword") inbody:keyword
In page .inpage("keyword") inpage:keyword
Language (ISO 639-1) .lang("es") lang:es
Language alias .language("es") language:es
Location (ISO 3166-1) .loc("gb") loc:gb
Location alias .location("gb") location:gb
Site / domain .site("example.com") site:example.com
Logical AND .and_(other) or & term1 AND term2
Logical OR .or_(other) or | term1 OR term2
Logical NOT .not_(other) or ~ NOT term

Operators can be placed anywhere in the query string, matching Brave Search behavior.

Most operator methods accept a single value or a list/tuple of values:

Query("AI startup").exclude(["google", "microsoft", "amazon"])
Query("news").site(["reuters.com", "bloomberg.com"])

Examples

Official documentation examples

from bsqb import Query

# Academic research
Query("climate change").filetype("pdf").site("edu").intitle("2024").build()
# climate change filetype:pdf site:edu intitle:2024

# Multilingual content
Query("recettes cuisine").loc("ca").lang("fr").build()
# recettes cuisine loc:ca lang:fr

# Competitive analysis
Query("AI startup").exclude(["google", "microsoft", "amazon", "meta"]).build()
# AI startup -google -microsoft -amazon -meta

# Technical documentation
(
    Query("python")
    .phrase("asyncio")
    .intitle("documentation")
    .site("docs.python.org")
    .build()
)
# python "asyncio" intitle:documentation site:docs.python.org

Logical operators

from bsqb import Query, combine_and, combine_or

# AND — visa info in English from UK sites
Query("visa").loc("gb").and_(Query().lang("en")).build()
# visa loc:gb AND lang:en

# OR — travel requirements for Australia or New Zealand
(
    Query("travel requirements")
    .inpage("australia")
    .or_(Query().inpage("new zealand"))
    .build()
)
# travel requirements inpage:australia OR inpage:"new zealand"

# NOT — exclude a domain
Query("brave search").not_(Query().site("brave.com")).build()
# brave search NOT site:brave.com

# Python operators
(Query("coffee") | Query("tea")).exclude("starbucks").build()
# coffee OR tea -starbucks

# Combine multiple queries
combine_and(Query("visa").loc("gb"), Query().lang("en")).build()
combine_or(Query().site("reuters.com"), Query().site("bloomberg.com")).build()
Query("news").site(["reuters.com", "bloomberg.com"]).build()

Advanced usage

from bsqb import Query, phrase, raw, term

# Build from AST nodes
Query.from_nodes(term("python"), phrase("asyncio"), raw("site:docs.python.org"))

# Wrap an existing query string
Query.parse("machine learning filetype:pdf lang:en").build()

# Skip validation for edge cases
Query.parse("...").build(validate=False)

Validation

The Brave Search API enforces these limits on the q parameter:

  • Maximum 400 characters
  • Maximum 50 words
  • Query cannot be empty

Call .build() to validate (default), or .render() / str() to get the string without validation:

from bsqb import Query, QueryValidationError, EmptyQueryError

query = Query("hello world")

query.render()   # "hello world" — no validation
query.build()    # "hello world" — validates limits

try:
    Query().build()
except EmptyQueryError:
    ...

try:
    Query.parse(" ".join(["word"] * 51)).build()
except QueryValidationError as exc:
    print(exc.query)

Integration with Brave Search API

Search operators are included in the q parameter. Set operators=true (the default) in API requests:

import urllib.parse
import urllib.request

from bsqb import Query

query = Query("python").phrase("asyncio").filetype("pdf").lang("en")

params = {
    "q": query.build(),
    "count": "10",
    "operators": "true",
}
url = "https://api.search.brave.com/res/v1/web/search?" + urllib.parse.urlencode(params)

request = urllib.request.Request(
    url,
    headers={
        "Accept": "application/json",
        "X-Subscription-Token": "YOUR_API_KEY",
    },
)

For POST requests with long queries, pass the built string as the q field in the request body.

Development

git clone https://github.com/kodzghly/bsqb.git
cd bsqb
python -m pip install -e ".[dev]"

# Run tests
pytest

# Lint and type check
ruff check src tests
mypy src

References

Support

If bsqb is useful to you, consider sponsoring on GitHub — it helps keep the project maintained.

License

MIT — see LICENSE.

Metadata

Release files for bsqb 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bsqb 0.2.1
File Size Uploaded Provenance Actions
bsqb-0.2.1.tar.gz 8.8 kB With provenance Details for bsqb-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bsqb 0.2.1
File Interpreter ABI Platform Actions
bsqb-0.2.1-py3-none-any.whl Python 3 none any Details for bsqb-0.2.1-py3-none-any.whl

Total release size: 19.7 kB

Release files / bsqb-0.2.1.tar.gz

Download URL bsqb-0.2.1.tar.gz
Size 8.8 kB
Tags Source
SHA-256 checksum
How to use checksums
74c4e35dba7b800feb7b070810bf35225de0fe8628c32b89867539d8f4db9e33
BLAKE2b-256 checksum
How to use checksums
a4b92eed053cb67cfec0fa161c6c84c90dc3dae22fffde8804c543f5dff33129
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

Release files / bsqb-0.2.1-py3-none-any.whl

Download URL bsqb-0.2.1-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
afd9348f37c78f44d931f52783764b9fdbcf6a9da082b43c32edb2d4d4245e4e
BLAKE2b-256 checksum
How to use checksums
37a20f6b76897620d4bea82afb28f24e72bb354f13a4e4d27a4dfbe9413e0dfa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

Security for bsqb 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for bsqb-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page