This Python module allows you to interact with IServ school servers using only login data for authentication. No API key is required.
pip install IServAPIfrom IServAPI import IServAPI
# Initialize IServ instance with login credentials
api = IServAPI(username="YOUR_ISERV_USERNAME",password="YOUR_ISERV_PASSWORD", iserv_url="some_iserv_url.de")
# Example: Get the current user's information
user_info = api.get_own_user_info()
print(user_info)- Unofficial IServ API
user_info = get_own_user_info()This method retrieves information about the currently logged-in user.
set_own_user_info(key=value)This method sets your personal information
Available keys are:
title
company
birthday
nickname
_class
street
zipcode
city
country
phone
mobilePhone
fax
mail
homepage
icq
jabber
msn
skype
note
notifications = get_notifications()Retrieves notifications from the specified URL and returns them as a JSON object.
badges = get_badges()Retrieves the badges from the IServ server. (Badges=numbers on sidebar)
read_all_notifications()Marks all Notification as read.
read_notification(notification_id)Marks a single notification as read.
get_disk_space()Returns information, like free disk space, label and color about all storage volumes accessible to you. (Windows account, Cloud, etc.)
get_user_profile_picture(user, output_folder)This method retrieves the avatar of any user on the network
It saves the avatar in the folder followed by the username,
search_users(query)users = search_users_autocomplete(query, limit=50)Faster than search_users() but may not display all users
get_user_info(user)Get someone else's public information this includes everything they heve set in 'Personal Information'
emails = get_emails(path = 'INBOX', length = 50, start = 0, order = 'date', dir = 'desc')Retrieves emails from a specified path with optional parameters for length, start, order, and direction.
email_info = get_email_info(path="INBOX", length=0, start=0, order="date", dir="desc")Retrieves email information from the specified path in the mailbox. For example: unread emails.
email_source = get_email_source(uid, path="INBOX")Retrieves the source code of an email message from the specified email path and message ID.
mail_folders = get_mail_folders()Retrieves the list of mail folders.
send_email(receiver_email:str, subject:str, body:str, html_body:str=None, smtp_server:str=None, smtps_port:int=465, attachments:list=None)Sends an email. Note all variables defaulting to none get defined later so don't worry.
sender_email must be a valid name present in the iserv network.
events = get_upcoming_events()Retrieves the upcoming events from the IServ calendar API.
events = get_events(start="2024-01-01", end="2025-12-31")Retrieves all events of all eventsources in the specified timeframe.
events = search_event(query="Party", start="2024-01-01", end="2025-12-31")Searches for an event in the specified timeframe.
events = api.get_calendar_plugin_events(
"holiday",
"2024.11.11",
"2026.11.11"
)Lists all events produced by a plugin. Plugins can be retrieved from the output of get_eventsources() where id is the plugin id if the type is plugin.
eventsources = get_eventsources()Retrieves the event sources from the calendar API.
status = delete_event(
uid="[email protected]",
_hash="541f2d74099d785d1286c03903a2e826",
calendar="/my.iserv.account/home",
start="2025-09-25T16:00:00+02:00",
series=True
)Deletes an event. All parameters, except series, are returned by get_events().
create_event(
subject = "Math exam",
calendar: "/my.iserv.user/home",
start: "27.09.2025 16:00",
end: "28.09.2025 10:00",
category: str = "exams",
location: str = "school",
alarms: = ["7D", "2D", "1D"],
isAllDayLong: bool = False,
description: str = "",
participants: list = [],
show_me_as: Literal["OPAQUE", "TRANSPARENT"] = "OPAQUE",
privacy: Literal["PUBLIC", "CONFIDENTIAL", "PRIVATE"] = "PUBLIC",
recurring: Recurring = {},
)Create a new event in the IServ calendar
This method constructs and submits an HTTP request to the IServ calendar API to create a new event with optional alarms, recurring patterns, and participants.
-
subject (
str):
The title or subject of the event. -
calendar (
str):
The ID of the calendar where the event will be created. -
start (
str):
Event start datetime in any format parsable bydateutil.parser. -
end (
str):
Event end datetime in any format parsable bydateutil.parser. -
category (
str, optional):
Category or tag for the event. Defaults to"". -
location (
str, optional):
Location of the event. Defaults to"". -
alarms (
list[AlarmType], optional):
List of alarms for the event. Each alarm can be:- A string:
"0M","5M","15M","30M","1H","2H","12H","1D","2D","7D" - A dictionary defining custom alarms:
- Custom datetime alarm:
alarms = [{"custom_date_time": {"dateTime": "dd.mm.YYYY HH:MM"}}]
- Custom interval alarm:
alarms = [{ "custom_interval": { "interval": { "days": int, "hours": int, "minutes": int, }, "before": bool, } }]
- Custom datetime alarm:
Defaults to
[]. - A string:
-
isAllDayLong (
bool, optional):
Whether the event lasts all day. Defaults toFalse. -
description (
str, optional):
Detailed description of the event. Defaults to"". -
participants (
list, optional):
List of participant identifiers (usernames or emails) to invite to the event. Defaults to[]. -
show_me_as (
Literal["OPAQUE", "TRANSPARENT"], optional):
Visibility of the event on your calendar."OPAQUE"blocks time."TRANSPARENT"shows availability.
Defaults to"OPAQUE".
-
privacy (
Literal["PUBLIC", "CONFIDENTIAL", "PRIVATE"], optional):
Privacy level of the event. Defaults to"PUBLIC". -
recurring (
Recurring, optional):
Dictionary defining recurring event rules. Example structure:{ "intervalType": "NO|DAILY|WEEKDAYS|WEEKLY|MONTHLY|YEARLY", "interval": int, # Only for types other than NO/WEEKDAYS "monthlyIntervalType": "BYMONTHDAY|BYDAY", # Required for MONTHLY "monthDayInMonth": int, # Required if BYMONTHDAY "monthInterval": str, # Required if BYDAY "monthDay": str, # Day of week if BYDAY "recurrenceDays": str, # Comma-separated weekdays if WEEKLY "endType": "NEVER|COUNT|UNTIL", "endInterval": int, # Required if COUNT "untilDate": str # Required if UNTIL, "DD.MM.YYYY" }
- All dates and times are automatically parsed and formatted to IServ's expected format.
- The method prints any error messages returned by the IServ API.
health = get_conference_health()Get the health status of the conference API endpoint.
client = file()Possible functions:
Synchronous methods
# Checking existence of the resource
client.check("dir1/file1")
client.check("dir1")# Get information about the resource
client.info("dir1/file1")
client.info("dir1/")# Check free space
free_size = client.free()# Get a list of resources
files1 = client.list()
files2 = client.list("dir1")# Create directory
client.mkdir("dir1/dir2")# Delete resource
client.clean("dir1/dir2")# Copy resource
client.copy(remote_path_from="dir1/file1", remote_path_to="dir2/file1")
client.copy(remote_path_from="dir2", remote_path_to="dir3")# Move resource
client.move(remote_path_from="dir1/file1", remote_path_to="dir2/file1")
client.move(remote_path_from="dir2", remote_path_to="dir3")# Move resource
client.download_sync(remote_path="dir1/file1", local_path="~/Downloads/file1")
client.download_sync(remote_path="dir1/dir2/", local_path="~/Downloads/dir2/")# Unload resource
client.upload_sync(remote_path="dir1/file1", local_path="~/Documents/file1")
client.upload_sync(remote_path="dir1/dir2/", local_path="~/Documents/dir2/")# Publish the resource
link = client.publish("dir1/file1")
link = client.publish("dir2")# Unpublish resource
client.unpublish("dir1/file1")
client.unpublish("dir2")# Get the missing files
client.pull(remote_directory='dir1', local_directory='~/Documents/dir1')# Send missing files
client.push(remote_directory='dir1', local_directory='~/Documents/dir1')Asynchronous methods
# Load resource
kwargs = {
'remote_path': "dir1/file1",
'local_path': "~/Downloads/file1",
'callback': callback
}
client.download_async(**kwargs)
kwargs = {
'remote_path': "dir1/dir2/",
'local_path': "~/Downloads/dir2/",
'callback': callback
}
client.download_async(**kwargs)# Unload resource
kwargs = {
'remote_path': "dir1/file1",
'local_path': "~/Downloads/file1",
'callback': callback
}
client.upload_async(**kwargs)
kwargs = {
'remote_path': "dir1/dir2/",
'local_path': "~/Downloads/dir2/",
'callback': callback
}
client.upload_async(**kwargs)For further informations visit CloudPolis/webdav-client-python
get_folder_size(path)Returns the size of a folder in human readable form.
get_goups()Returns a JSON object with all the group names as key and their ID as value.
Add this
IServAPI.setup_logging("app.log")after your from IServAPI import IServAPI
- add search users
- more functionality
- make wiki
- Add calendar modification capabilities
Contributions are welcome! If you'd like to contribute to this project, please fork the repository and submit
a pull request. Make sure to follow the existing code style and add appropriate tests for new functionality.
- Author @Leo-Aqua
- Author of WebDAV client Python @CloudPolis
This project is licensed under the MIT License - see the LICENSE file for details.