bsqb
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.typedmarker 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,NOTwith 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.