Search, filter and sort iCalendar components
Project description
icalendar-searcher
This library should contain logic for searching, filtering and sorting icalendar data, as well as logic for storing and representing an icalendar search query.
Audience
- This will be used for the python CalDAV client library, both for bundling search parameters together in one object, for doing client-side filtering when the server does not support the desired search query.
- This may be useful in any kind of software handling collections of calendar content and needing to do filtering or searches on it.
- This may also be useful by calendar server developers.
Usage
No proper usage documentation has been written yet, sorry. There are tons of inline comments and docstrings though. The AI has contributed with quite some verbose comments in the test code, but little of it has been exposed to any proper QA.
Basic Example
from icalendar_searcher import Searcher
from datetime import datetime
# Create a searcher with filters
searcher = Searcher(
event=True, # Only events
start=datetime(2025, 1, 1),
end=datetime(2025, 12, 31)
)
# Add property filters
searcher.add_property_filter("SUMMARY", "meeting", operator="contains")
searcher.add_property_filter("LOCATION", "Office", operator="contains", case_sensitive=False)
# Check if a component matches
result = searcher.check_component(calendar)
Case-Sensitive vs Case-Insensitive Filtering
By default, text filtering is case-sensitive. You can make it case-insensitive:
# Case-insensitive search (simple API)
searcher.add_property_filter("SUMMARY", "meeting", case_sensitive=False)
# Case-sensitive search (default)
searcher.add_property_filter("SUMMARY", "Meeting")
Case-insensitivity is not straight-forward. It may cause non-deterministic sort results, and there may be problems with unicode characters - i.e., according to the CalDAV standard, case-insensitivity should only apply to ASCII-characters - causing mismatches between naïve and NAÏVE, cliché and CLICHÉ, smörgåsbord and SMØRGÅSBORD, not to forget millions of words in non-English languages, complete non-latin scripts, etc. While this library handles Unicode well, the CalDAV library will by default ask the server to do the search.
Category Filtering
Two virtual properties are available for filtering by categories:
- "categories" (plural): Categories is considered to be a set of categories to be matched with the set of categories found in the event. If categories is given as a string, it will be split by the commas.
- "category" (singular): Category is considered to be a string, to be matched literally towards at least one of the categories in the event.
Examples:
# Match events with both "WORK" and "URGENT" categories (exact match)
searcher.add_property_filter("categories", "WORK,URGENT", operator="contains")
# Match events where any category contains "out" (e.g., "outdoor", "outing")
searcher.add_property_filter("category", "out", operator="contains")
Advanced Collation (requires PyICU)
For advanced Unicode and locale-aware text comparison, install with:
pip install 'icalendar-searcher[collation]'
Then use locale-specific sorting:
from icalendar_searcher.collation import Collation
searcher.add_property_filter("SUMMARY", "Müller",
collation=Collation.LOCALE,
locale="de_DE")
Related projects
- The project depends on the icalendar library, all calendar contents handled by this library is coming in and out as
icalendar.Componentoricalendar.Calendar. However, the library should also support wrapped objects (like instances of thecaldav.Eventclass). - The project depends on the recurring-ical-events library for expanding recurrence sets.
- The project is used by the Python CalDAV client library
Status as of v0.3.1
This library still has some stubbed implementations: in particular searcher.filter() and searcher.sort. Since the logic has been implemented, those should be really straight-forward to implement, it's just a matter of deciding the acceptable input and output parameter types.
Only operators supported so far is ==, contains and undef. Other operators like !=/<>, <, <=, ~, etc has not been implemented.
As for now, the maintainers primary priority is to develop whatever is needed for supporting the next release of the CalDAV library.
According to the SemVer rules, it's OK to still change the API in 0.x-versions, but the current API is likely to be quite stable. See CHANGELOG.md for version history and breaking changes.
History
This is a spin-off from the python caldav project, started by Tobias Brox in 2025-11, the maintainer of the Python CalDAV client library at that time, in collaboration with the main contributors of the icalendar library.
AI
The author has been experimenting a bit with AI usage while creating this project, both GitHub Copilot and Claude has been tested. Most of the test code has been created by the AI. AI has also been utilized a bit for refactoring, bug hunting, and a little bit code generation (particularly wrg of the collations support), but most of the "business logic" was written by me.
While all the AI-generated changes in the business logic has been looked through thoroughly, very little QA has been done on the test code.
Performance
In the early versions, the filter method will take the calendar contents one by one and check if it matches or not. This will work out well enough for small calendar sets. If lots of searches are to be done on fairly static data (like what typically may happen at the server side in a calendaring system), then it would be an idea to add indexes.
The expansion part may cause millions of recurrences to be created. It even supports open-ended intervals. It's possible by returning generators. However, things will most likely blow up and eat all the CPU and memory it gets the hands on whenever one wants to do sorting of such a thing.
License
As for now I'm releasing this under the GNU Affero General Public License v.3.0. If you find this too restrictive or if this causes license compatibility issues for you, I will consider to fix some dual licensing, like it's done with the python CalDAV library.
This also means that any contributor has to accept that the code is released under AGPL v3.0 and at some point in the future may be dual-licensed under some more permissive license, like the EUPL v1.1.
I don't have very strong opinions on licenses. If you have any issues in one way or another, please reach out.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file icalendar_searcher-0.4.1.tar.gz.
File metadata
- Download URL: icalendar_searcher-0.4.1.tar.gz
- Upload date:
- Size: 33.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
588566330c484511a8095e2aabf79a8c0d6facf91252445486ba243b177a53af
|
|
| MD5 |
2631e01a4e8489ba84641f941f586dce
|
|
| BLAKE2b-256 |
e5a8b2c9129d35d8efa96ea6c3111517af3109c6e103936732b1ba20003de923
|
Provenance
The following attestation bundles were made for icalendar_searcher-0.4.1.tar.gz:
Publisher:
publish.yaml on python-caldav/icalendar-searcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
icalendar_searcher-0.4.1.tar.gz -
Subject digest:
588566330c484511a8095e2aabf79a8c0d6facf91252445486ba243b177a53af - Sigstore transparency entry: 728290804
- Sigstore integration time:
-
Permalink:
python-caldav/icalendar-searcher@d7f9111f0ffe9174bee94251a9ada93c752b73f7 -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/python-caldav
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@d7f9111f0ffe9174bee94251a9ada93c752b73f7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file icalendar_searcher-0.4.1-py3-none-any.whl.
File metadata
- Download URL: icalendar_searcher-0.4.1-py3-none-any.whl
- Upload date:
- Size: 33.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
326eae5e43c8dc6ce971f0f5ccb5bbd48667ac4b9dff12fc6890a06989c9320e
|
|
| MD5 |
c5b75bb2f4d575ab7ebba68745e2c1cf
|
|
| BLAKE2b-256 |
464b451e07b1a5fbc04f3627450ccfc77bc939b8fce9f4ddae59fc3c86e50e79
|
Provenance
The following attestation bundles were made for icalendar_searcher-0.4.1-py3-none-any.whl:
Publisher:
publish.yaml on python-caldav/icalendar-searcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
icalendar_searcher-0.4.1-py3-none-any.whl -
Subject digest:
326eae5e43c8dc6ce971f0f5ccb5bbd48667ac4b9dff12fc6890a06989c9320e - Sigstore transparency entry: 728290813
- Sigstore integration time:
-
Permalink:
python-caldav/icalendar-searcher@d7f9111f0ffe9174bee94251a9ada93c752b73f7 -
Branch / Tag:
refs/tags/v0.4.1 - Owner: https://github.com/python-caldav
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@d7f9111f0ffe9174bee94251a9ada93c752b73f7 -
Trigger Event:
push
-
Statement type: