Skip to main content

decidalo_client.py

License: MIT Python Versions (officially) supported Pypi status badge

Unittests status badge Coverage status badge Linting status badge Formatting status badge

This repository contains two async Python clients for decidalo:

Client API Purpose
DecidaloClient (Import Client) V3 Import API Bulk-importing data (users, teams, projects, bookings, ...) into decidalo
DecidaloAppClient (App Client) App API (api.decidalo.app) Reading data from decidalo: searching people, viewing profiles, skills, certificates, projects

Use the Import Client when you need to push data into decidalo (e.g. syncing users from an HR system). Use the App Client when you need to read data from decidalo (e.g. finding people with specific skills).

[!IMPORTANT] This is a community project and is NOT an official decidalo client. It is not affiliated with or endorsed by Data Assessment Solutions GmbH.

Installation

pip install decidalo-client

Import Client (DecidaloClient)

The Import Client wraps the decidalo V3 Import API (Swagger UI). It is used for bulk-importing data into decidalo using an API key.

import asyncio
from decidalo_client import DecidaloClient, DecidaloAPIError, DecidaloAuthenticationError

async def main() -> None:
    async with DecidaloClient(api_key="your-api-key") as client:
        # Get all users
        users = await client.get_users()
        for user in users:
            print(f"{user.displayName} ({user.email})")

        # Get all projects
        projects = await client.get_all_projects()
        for project in projects:
            print(f"{project.properties.name.value}")

if __name__ == "__main__":
    asyncio.run(main())

Error Handling

import asyncio
from decidalo_client import DecidaloClient, DecidaloAPIError, DecidaloAuthenticationError

async def main() -> None:
    async with DecidaloClient(api_key="your-api-key") as client:
        try:
            users = await client.get_users()
        except DecidaloAuthenticationError as e:
            print(f"Authentication failed: {e.message}")
        except DecidaloAPIError as e:
            print(f"API error {e.status_code}: {e.message}")

if __name__ == "__main__":
    asyncio.run(main())

Import Client Features

  • Async HTTP client built on aiohttp
  • Type-safe request/response models using pydantic
  • All major API endpoints:
    • Users - Get users, import users (sync/async), check import status, get employee types
    • Teams - Get teams, import teams (sync/async), check import status
    • Companies - Get companies, import companies
    • Projects - Get projects, get all projects, import projects (single/batch), check existence, get contacts, get team members, get/import recording targets
    • Bookings - Get bookings, get bookings by project, import bookings
    • Absences - Get absences, import absences
    • Resource Requests - Get resource requests, import resource requests, get contacts
    • Roles - Import roles
    • Working Time Patterns - Get working time patterns, import working time patterns
    • Orders - Get/import orders and order positions, custom properties, recording targets, work-package links
    • Work Packages - Get/import work packages, candidates, order-position links, recording targets
    • Time Recording - Get recording targets, get/import user timesheets
    • Activities - Get/import activity types and general activities
    • Profile Exports - Get industries, languages, professional experience, publications, testimonials, trainings, and get/import assessed skills

App Client (DecidaloAppClient)

The App Client wraps the decidalo App API (api.decidalo.app). It is used for reading data from decidalo — searching for people, viewing profiles, exploring skills, certificates, and projects.

[!NOTE] The App API does not have a public Swagger UI. The client was reverse-engineered from the decidalo web application.

Authentication

The App Client authenticates via OAuth2 (Microsoft SSO) through login.decidalo.app. There are two authentication flows:

  1. Device Code Flow (interactive, for first-time setup) — prints a URL and code to the console for you to open in a browser.
  2. Refresh Token Flow (headless, for automation) — reuses a previously obtained refresh token.
import asyncio
from decidalo_app_client import DecidaloAppClient
from decidalo_app_client.auth import DecidaloAuth

async def first_time_login() -> None:
    """Interactive login — run this once to obtain a refresh token."""
    token = await DecidaloAuth.device_code_login()
    # The device code flow prints a URL and code to the console.
    # Open the URL in your browser and enter the code to authenticate.
    print(f"Save this refresh token for future use: {token.refresh_token}")

asyncio.run(first_time_login())

Store the refresh token securely (e.g. in an environment variable or a secrets manager). For subsequent runs, use the refresh token:

token = await DecidaloAuth.refresh("your-saved-refresh-token")

Minimal Working Example

import asyncio
from decidalo_app_client import DecidaloAppClient
from decidalo_app_client.auth import DecidaloAuth

async def main() -> None:
    # Use a refresh token obtained from a previous device_code_login()
    token = await DecidaloAuth.refresh("your-saved-refresh-token")

    async with DecidaloAppClient(token=token) as client:
        # Search for people with specific skills
        results = await client.search.find_people(keywords=["SAP", "Python"])
        for user in results.usersWithMatchedQualities:
            print(f"User {user.userId} (Score: {user.score})")

        # Get a user's profile header
        header = await client.profile.get_header(user_id=42)
        print(f"Profile quality: {header.profileQuality}, last edited by: {header.lastEditor}")

        # Browse available skill categories
        categories = await client.skills.get_categories()
        for cat in categories:
            print(f"Category: {cat.categoryName}")

asyncio.run(main())

You can also pass a static Bearer token string directly if you manage tokens yourself:

async with DecidaloAppClient(token="your-bearer-token") as client:
    ...

App Client Features

  • Async HTTP client built on aiohttp with automatic token refresh
  • OAuth2 Device Code Flow and Refresh Token Flow (direct OIDC HTTP, no extra dependency)
  • Type-safe Pydantic models for most responses
  • Domain-based API structure:
    • Search — Find people by skills/keywords, autocomplete user names, get filter fields
    • Profile — Read profile headers, skills, certificates, languages, industries, roles, competencies, projects
    • Projects — Get project headers, overviews, details, team members, references
    • Skills — Autocomplete skills, get levels, categories, skill grids, assessments
    • Certificates — Autocomplete certificates, get holders, certificate grids
    • Roles — Get roles, check user skills/certificates against role requirements
    • Teams — Get team details, find teams by manager, get members under current user

Development

Clone the repository and install the development environment:

git clone https://github.com/Hochfrequenz/decidalo_client.py.git
cd decidalo_client.py
uv sync --group dev

To regenerate the Pydantic models from the OpenAPI spec:

uv run --group codegen datamodel-codegen --input openapi/v1/swagger.json --output src/decidalo_client/models/_autogenerated.py --input-file-type openapi --output-model-type pydantic_v2.BaseModel --target-python-version 3.11 --use-annotated --use-double-quotes --collapse-root-models --field-constraints --strict-nullable --use-standard-collections --enum-field-as-literal one
uv run --group codegen ruff format src/decidalo_client/models/_autogenerated.py
uv run --group codegen ruff check --select I --fix src/decidalo_client/models/_autogenerated.py

For detailed information on the development setup (uv configuration, IDE setup, etc.), see the Hochfrequenz Python Template Repository.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

decidalo_client-0.2.2.tar.gz (245.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

decidalo_client-0.2.2-py3-none-any.whl (64.3 kB view details)

Uploaded Python 3

File details

Details for the file decidalo_client-0.2.2.tar.gz.

File metadata

  • Download URL: decidalo_client-0.2.2.tar.gz
  • Upload date:
  • Size: 245.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for decidalo_client-0.2.2.tar.gz
Algorithm Hash digest
SHA256 20c95a2289a11869877f5f730d23352ca608f19b923cbbc91047748534d1d97c
MD5 973c8f7aa19cf646f323e62c5895401a
BLAKE2b-256 b4603f88faf7ecc71da14a0939959df9aeaf8139d25d7d7580ab4ba3b2f41897

See more details on using hashes here.

File details

Details for the file decidalo_client-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: decidalo_client-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 64.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for decidalo_client-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c2143ffa979ede706783ccfbd017feaffe5e2004f2ae5c41aae5de560c21c9f5
MD5 19cbd0cd5d5b2f1ebee37573af8a3b2b
BLAKE2b-256 328a1c86282dc18bbc9fec2c1cc9531420b575eabceb8dd132789dc5380af722

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.2

2 files

0.0.1

2 files

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