Skip to content

Planka Interface

interface

Base interface for Planka

When reading the documentation, all returned list[PlankaModel] types are actually models.ModelLists at runtime. These will also be properly type hinted by your static type checker and expose some alternate ways of indexing into model lists:

Example:

>>> type(planka.projects)
ModelList

# Using an exact schema filter
>>> planka.projects[{'name': 'My Project'}]
[Project(name='My Project', ...)]

# Using a functional schema filter (name is replaced with the value of name)
>>> planka.projects[{'name': lambda name: 'My' in name}]
[Project(name='My Project', ...), Project(name='My Other Project', ...)]

# Using a model filter
>>> planka.projects[lambda project: project.owner == planka.me]
[<previous results>..., Project('Another Project I Own', ...)]

All dictionary based schema filtering can be done per key and the model will only be included in the output if all filters match.

Additionally, a dpop method is included that allows popping from a model list with a default value if no results

>>> filtered = to_do_list.cards[lambda c: c.due_date and (c.due_date - datetime.now()).days < 4]
>>> if next_card := filtered.dpop():
...     print(next_card.url)
...     print(next_card.name)
... else:
...     print('No results')
https://planka.mydomain.com/cards/1234...
'Critical Project'
--or--
No results

CLASS DESCRIPTION
Planka

Root object for connecting to a Planka instance

Planka

Planka(base_url: str | URL | None = None, *, client: Client | None = None, timezone: timezone = utc)

Root object for connecting to a Planka instance

A Planka instance can be initialized using a base_url or a httpx.Client objcet. If both arguments are passed, the base_url of the passed client will be overriden with the url passed to the base_url argument

Example
# Using the default client
>>> planka = Planka('https://planka.example.com')
... planka.client
<httpx.Client object at 0x...>

>>> planka.client.base_url
URL('https://planka.example.com')

# Using a pre-configured client
>>> hooks = {'request': [hook1, hook2], 'response': [hook3, hook4]}
... client = Client(event_hooks=hooks)
... planka = Planka('https://planka.example.com', client=client)
... planka.client.event_hooks
{'request': [<hook1>, <hook2>], 'response': [<hook3>, <hook4>]}

All Planka sessions will respect the configuration of the passed client object. For more configuration options, see the httpx docs: https://www.python-httpx.org/advanced/clients/

After initializing, the Planka instance required the authorization flow to take place using the login method

Example

>>> # Using an API key
... planka.login(api_key='<my_api_key>')
... planka.projects
[Project(...), Project(...), ...]
>>> # First time login (accept instance ToS)
... planka.login(username='me@email.com', password='mypassword', accept_terms=True)
TERMS OF SERVICE
--- More ToS ---

>>> planka.projects
[Project(...), Project(...), ...]

Logging in with a username and password will work, but it's best practice to authenticate using an api key, which you can get from your instance administrator.

PARAMETER DESCRIPTION

base_url

The base url of the instance (e.g. https://planka.app)

TYPE: str | URL | None DEFAULT: None

client

An optional pre-configured httpx.Client object to use as the session client

TYPE: Client | None DEFAULT: None

timezone

An optional timezone to cast all datetimes to for date math

TYPE: timezone DEFAULT: utc

RAISES DESCRIPTION
ValueError

If no base_url or no client with a base_url

METHOD DESCRIPTION
accept_terms

If the User has never logged on, or is required to accept new terms, allow them to do so

create_project

Creates a project. The current user automatically becomes a project manager.

create_user

Creates a user account. Requires admin privileges.

create_webhook

Create a Webhook. Requires admin

login

Authenticate with the planka instance

logout

Logout the current User

read_notifications

Read all Notifications for the current User

ATTRIBUTE DESCRIPTION
config

Get the configuration info for the current Planka server

TYPE: Config

me

Get the User object for the currently logged in user

TYPE: User

notifications

Get all notifications for the current User

TYPE: list[Notification]

projects

Get all Projects available to the current user

TYPE: list[Project]

unread_notifications

Get all unread Notifications for the current user

TYPE: list[Notification]

users

Get all Users on the current instance (requires admin or projectOwner role)

TYPE: list[User]

webhooks

Get all configured Webhooks (requires admin)

TYPE: list[Webhook]

Source code in src/plankapy/v2/interface.py
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
def __init__(self, 
             base_url: str|URL|None=None, 
             *, 
             client: Client|None=None, 
             timezone: timezone = timezone.utc) -> None:
    """
    Args:
        base_url: The base url of the instance (e.g. `https://planka.app`)
        client: An optional pre-configured `httpx.Client` object to use as the session client
        timezone: An optional timezone to cast all datetimes to for date math

    Raises:
        ValueError: If no base_url or no client with a base_url
    """
    if client is None and base_url:
        self.client = Client(base_url=base_url)
    elif client and base_url is None:
        if not client.base_url:
            raise ValueError(
                f'If using a client, the client\'s base_url attribute must be set '
                'or a base_url must be passed to the Planka initializer'
            )
        self.client = client
    elif base_url and client:
        self.client = client
        self.client.base_url = base_url
    else:
        raise ValueError(f'base_url and/or client must be passed')

    self.endpoints = PlankaEndpoints(self.client)
    self.timezone = timezone

    # Assigned after login() is called
    self.current_role: UserRole | None = None
    self.current_id : str | None = None

config cached property

config: Config

Get the configuration info for the current Planka server

me cached property

me: User

Get the User object for the currently logged in user

notifications property

notifications: list[Notification]

Get all notifications for the current User

projects property

projects: list[Project]

Get all Projects available to the current user

Note

admins will get all instance Projects projectOwners will get all owned projects and shared projects all others will get only assigned and shared projects

unread_notifications property

unread_notifications: list[Notification]

Get all unread Notifications for the current user

users property

users: list[User]

Get all Users on the current instance (requires admin or projectOwner role)

Note

projectOwners will only get Users in their Projects admins will get all instance Users all others will get an empty list

webhooks property

webhooks: list[Webhook]

Get all configured Webhooks (requires admin)

accept_terms

accept_terms(pending_token: str, terms_type: TermsType = 'general', lang: Language = 'en-US')

If the User has never logged on, or is required to accept new terms, allow them to do so

Source code in src/plankapy/v2/interface.py
154
155
156
157
158
159
def accept_terms(self, pending_token: str, terms_type: TermsType='general', lang: Language='en-US'):
    """If the User has never logged on, or is required to accept new terms, allow them to do so"""
    terms = self.endpoints.getTerms(type=terms_type, language=lang)['item']
    print(terms['content'])
    sig = terms['signature']
    self.endpoints.acceptTerms(pendingToken=pending_token, signature=sig)

create_project

create_project(*, name: str, type: ProjectType, description: str | None = None) -> Project

Creates a project. The current user automatically becomes a project manager.

Must be a Project Owner or an Admin

PARAMETER DESCRIPTION
type

Type of the project

TYPE: ProjectType

name

Name/title of the project

TYPE: str

description

Detailed description of the project

TYPE: str | None DEFAULT: None

Source code in src/plankapy/v2/interface.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def create_project(self, 
                   *,
                   name: str,
                   type: ProjectType,
                   description: str|None=None) -> Project:
    """Creates a project. The current user automatically becomes a project manager.

    Must be a Project Owner or an Admin

    Args:
        type: Type of the project
        name: Name/title of the project
        description: Detailed description of the project
    """
    return Project(
        self.endpoints.createProject(
            name=name, 
            type=type, 
            description=description,
        )['item'], 
        self
    )

create_user

create_user(*, email: str, password: str, role: UserRole, name: str, username: str | None = None, phone: str | None = None, organization: str | None = None, language: Language | None = None, subscribe_to_own_cards: bool = False, subscribe_to_cards_when_commenting: bool = True, turn_off_recent_card_highlighting: bool = False) -> User

Creates a user account. Requires admin privileges.

Only email, password, role, and name are required

PARAMETER DESCRIPTION
email

Email address for login and notifications

TYPE: str

password

Password for user authentication (must meet password requirements)

TYPE: str

role

User role defining access permissions

TYPE: UserRole

name

Full display name of the user

TYPE: str

username

Unique username for user identification

TYPE: str DEFAULT: None

phone

Contact phone number

TYPE: str DEFAULT: None

organization

Organization or company name

TYPE: str DEFAULT: None

language

Preferred language for user interface and notifications (example: en-US)

TYPE: LanguageCode DEFAULT: None

subscribe_to_own_cards

Whether the user subscribes to their own cards

TYPE: bool DEFAULT: False

subscribe_to_cards_when_commenting

Whether the user subscribes to cards when commenting

TYPE: bool DEFAULT: True

turn_off_recent_card_highlighting

Whether recent card highlighting is disabled

TYPE: bool DEFAULT: False

Source code in src/plankapy/v2/interface.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
def create_user(self, 
                *,
                email: str,
                password: str,
                role: UserRole,
                name: str,
                username: str|None=None,
                phone: str|None=None,
                organization: str|None=None,
                language: Language|None=None,
                subscribe_to_own_cards: bool=False,
                subscribe_to_cards_when_commenting: bool=True,
                turn_off_recent_card_highlighting: bool=False) -> User:
    """Creates a user account. Requires admin privileges.

    Only `email`, `password`, `role`, and `name` are required

    Args:
        email (str): Email address for login and notifications
        password (str): Password for user authentication (must meet password requirements)
        role (UserRole): User role defining access permissions
        name (str): Full display name of the user
        username (str): Unique username for user identification
        phone (str): Contact phone number
        organization (str): Organization or company name
        language (LanguageCode): Preferred language for user interface and notifications (example: `en-US`)
        subscribe_to_own_cards (bool): Whether the user subscribes to their own cards
        subscribe_to_cards_when_commenting (bool): Whether the user subscribes to cards when commenting
        turn_off_recent_card_highlighting (bool): Whether recent card highlighting is disabled
    """

    return User(
        self.endpoints.createUser(
            email=email,
            password=password,
            role=role,
            name=name,
            username=username,
            phone=phone,
            organization=organization,
            language=language,
            subscribeToOwnCards=subscribe_to_own_cards,
            subscribeToCardWhenCommenting=subscribe_to_cards_when_commenting,
            turnOffRecentCardHighlighting=turn_off_recent_card_highlighting,
        )['item'], 
        self
    )

create_webhook

create_webhook(*, name: str, url: str, access_token: str | None = None, events: Sequence[PlankaEvent] | None = None, excluded_events: Sequence[PlankaEvent] | None = None) -> Webhook

Create a Webhook. Requires admin

PARAMETER DESCRIPTION
name

Name/title of the webhook

TYPE: str

url

URL endpoint for the webhook

TYPE: str

access_token

Access token for webhook authentication

TYPE: str | None DEFAULT: None

events

list of events that trigger the webhook

TYPE: Sequence[PlankaEvent] | None DEFAULT: None

excluded_events

Comma-separated list of events excluded from the webhook

TYPE: Sequence[PlankaEvent] | None DEFAULT: None

Source code in src/plankapy/v2/interface.py
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
def create_webhook(self, 
                   *,
                   name: str,
                   url: str,
                   access_token: str|None=None,
                   events: Sequence[events.PlankaEvent]|None=None,
                   excluded_events: Sequence[events.PlankaEvent]|None=None) -> Webhook:
    """Create a Webhook. Requires admin

    Args:
        name: Name/title of the webhook
        url: URL endpoint for the webhook
        access_token: Access token for webhook authentication
        events: list of events that trigger the webhook
        excluded_events: Comma-separated list of events excluded from the webhook
    """
    args = {
        'name': name,
        'url': url
    }
    if events:
        args['events'] = ','.join(events)
    if excluded_events:
        args['excludedEvents'] = ','.join(excluded_events)
    if access_token:
        args['accessToken'] = access_token
    return Webhook(self.endpoints.createWebhook(**args)['item'], self)

login

login(*, username: str | None = None, password: str | None = None, api_key: str | None = None, accept_terms: TermsType | None = None, terms_lang: Language = 'en-US') -> None

Authenticate with the planka instance

PARAMETER DESCRIPTION
username

User username/email

TYPE: str | None DEFAULT: None

password

User password

TYPE: str | None DEFAULT: None

api_key

User API Key

TYPE: str | None DEFAULT: None

accept_terms

If you user has not accepted the terms, run the term acceptance flow

TYPE: TermsType | None DEFAULT: None

terms_lang

If accepting terms, request them in this language

TYPE: Language DEFAULT: 'en-US'

Note

After accepting the terms, please get an API key from the Planka server. If you need to accept extended terms, please set the terms flag to the terms you are accepting. These terms will be printed to stdout during the flow.

Source code in src/plankapy/v2/interface.py
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def login(self, 
          *, 
          username: str|None=None, 
          password: str|None=None, 
          api_key: str|None=None, 
          accept_terms: TermsType | None=None,
          terms_lang: Language='en-US') -> None:

    """Authenticate with the planka instance

    Args:
        username (str | None): User username/email 
        password (str | None): User password
        api_key (str | None): User API Key
        accept_terms (TermsType | None): If you user has not accepted the terms, run the term acceptance flow
        terms_lang: If accepting terms, request them in this language

    Note:
        After accepting the terms, please get an API key from the Planka server. If you need to accept extended terms, please 
        set the `terms` flag to the terms you are accepting. These terms will be printed to `stdout` during the flow.
    """
    # API Key
    if api_key:
        self.client.headers['X-Api-Key'] = api_key

    # User/Pass with term acceptance flow
    elif username and password:
        try:
            # Get Bearer Auth
            token = self.endpoints.createAccessToken(emailOrUsername=username, password=password, withHttpOnlyToken=True)['item']
            self.client.headers['Authorization'] = f'Bearer {token}'
        except HTTPStatusError as e:
            if accept_terms is None:
                raise PermissionError(f'Please logon again with `accept_terms` set to the terms you must accept')
            self.accept_terms(e.response.json()['pendingToken'], terms_type=accept_terms, lang=terms_lang)
            self.login(username=username, password=password)

    # Invalid Creds
    else:
        raise PermissionError(f'No credentials supplied! Must provide a user/password or an api_key')

    self.current_role = self.me.role
    self.current_id = self.me.id

logout

logout() -> None

Logout the current User

Source code in src/plankapy/v2/interface.py
205
206
207
def logout(self) -> None:
    """Logout the current User"""
    self.endpoints.deleteAccessToken()

read_notifications

read_notifications() -> list[Notification]

Read all Notifications for the current User

Source code in src/plankapy/v2/interface.py
269
270
271
272
@model_list
def read_notifications(self) -> list[Notification]:
    """Read all Notifications for the current User"""
    return [Notification(n, self) for n in self.endpoints.readAllNotifications()['items']]