Skip to content

Project Structure

src/toggl_api
├── asyncio
│   ├── _async_cache.py
│   ├── _async_client.py
│   ├── _async_endpoint.py
│   ├── _async_organization.py
│   ├── _async_project.py
│   ├── _async_reports.py
│   ├── _async_sqlite_cache.py
│   ├── _async_tag.py
│   ├── _async_tracker.py
│   ├── _async_user.py
│   ├── _async_workspace.py
│   └── __init__.py
├── _client.py
├── config.py
├── _exceptions.py
├── __init__.py
├── meta
│   ├── _base_endpoint.py
│   ├── _body.py
│   ├── cache
│   │   ├── _base_cache.py
│   │   ├── __init__.py
│   │   ├── _json_cache.py
│   │   └── _sqlite_cache.py
│   ├── _cached_endpoint.py
│   ├── _enums.py
│   └── __init__.py
├── models
│   ├── _decorators.py
│   ├── __init__.py
│   ├── _models.py
│   └── _schema.py
├── _organization.py
├── _project.py
├── py.typed
├── reports.py
├── _tag.py
├── _tracker.py
├── _user.py
├── _utility.py
├── _version.py
└── _workspace.py

5 directories, 39 files

Class Diagram

classDiagram
  class AsyncClientEndpoint {
    MODEL
    endpoint
    workspace_id
    add(body: ClientBody) TogglClient
    collect(body: ClientBody | None) list[TogglClient]
    delete(client: TogglClient | int) None
    edit(client: TogglClient | int, body: ClientBody) TogglClient
    get(client_id: int | TogglClient) TogglClient | None
  }
  class AsyncDetailedReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats, pagination: PaginationOptions | None) PaginatedResult[bytes]
    search_time_entries(body: ReportBody, pagination: PaginationOptions | None) PaginatedResult[list[dict[str, Any]]]
    totals_report(body: ReportBody) dict[str, int]
  }
  class AsyncOrganizationEndpoint {
    MODEL
    add(name: str, workspace_name: str) TogglOrganization
    collect() list[TogglOrganization]
    delete(organization: TogglOrganization | int) None
    edit(organization: TogglOrganization | int, name: str) TogglOrganization
    get(organization: TogglOrganization | int) TogglOrganization | None
  }
  class AsyncProjectEndpoint {
    BASIC_COLORS : Final[dict[str, str]]
    MODEL
    endpoint
    workspace_id
    add(body: ProjectBody) TogglProject
    collect(body: ProjectBody | None) list[TogglProject]
    delete(project: TogglProject | int) None
    edit(project: TogglProject | int, body: ProjectBody) TogglProject
    get(project_id: int | TogglProject) TogglProject | None
    get_color(name: str) str
    get_color_id(color: str) int
    status_to_query(status: TogglProject.Status, statement: Select[Any]) Select[Any]
  }
  class AsyncReportEndpoint {
    BASE_ENDPOINT : ClassVar[URL]
    workspace_id
    export_report(body: ReportBody)* Any
    search_time_entries(body: ReportBody)* Any
  }
  class AsyncSqliteCache {
    cache_path
    database
    metadata
    add() None
    delete() None
    find(pk: int) T | None
    load() list[T]
    update() None
  }
  class AsyncSummaryReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats) bytes
    project_summaries(start_date: date | str, end_date: date | str) list[dict[str, int]]
    project_summary(project: TogglProject | int, start_date: date | str, end_date: date | str) dict[str, int]
    search_time_entries(body: ReportBody) list[dict[str, int]]
  }
  class AsyncTagEndpoint {
    MODEL
    endpoint
    workspace_id
    add(name: str) TogglTag
    collect() list[TogglTag]
    delete(tag: TogglTag | int) None
    edit(tag: TogglTag | int, name: str) TogglTag
    get(tag: TogglTag | int) TogglTag | None
  }
  class AsyncTrackerEndpoint {
    MODEL
    TRACKER_ALREADY_STOPPED : Final[int]
    TRACKER_NOT_RUNNING : Final[int]
    endpoint
    workspace_id
    add(body: TrackerBody) TogglTracker
    bulk_edit() Edits
    collect(since: int | datetime | None, before: date | None, start_date: date | None, end_date: date | None) list[TogglTracker]
    current() TogglTracker | None
    delete(tracker: TogglTracker | int) None
    edit(tracker: TogglTracker | int, body: TrackerBody) TogglTracker
    get(tracker_id: int | TogglTracker) TogglTracker | None
    stop(tracker: TogglTracker | int) TogglTracker | None
  }
  class AsyncUserEndpoint {
    get_details() dict[str, Any]
  }
  class AsyncWeeklyReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats) bytes
    search_time_entries(body: ReportBody) list[dict[str, Any]]
  }
  class AsyncWorkspaceEndpoint {
    MODEL
    organization_id
    add(body: WorkspaceBody) TogglWorkspace
    collect(since: datetime | int | None) list[TogglWorkspace]
    edit(workspace_id: TogglWorkspace | int, body: WorkspaceBody) TogglWorkspace
    get(workspace: TogglWorkspace | int) TogglWorkspace | None
    statistics(workspace_id: TogglWorkspace | int) WorkspaceStatistics
    tracker_constraints(workspace_id: TogglWorkspace | int) dict[str, bool]
  }
  class AuthenticationError {
  }
  class BaseBody {
    format(endpoint: str)* dict[str, Any]
  }
  class BulkEditParameter {
    op : Literal['add', 'remove', 'replace']
    path : str
    value : Any
  }
  class CacheCallable {
  }
  class ClientBody {
    name : str | None
    notes : str | None
    status : CLIENT_STATUS | None
    format(endpoint: str) dict[str, Any]
  }
  class ClientEndpoint {
    MODEL
    endpoint
    workspace_id
    add(body: ClientBody) TogglClient
    collect(body: ClientBody | None) list[TogglClient]
    delete(client: TogglClient | int) None
    edit(client: TogglClient | int, body: ClientBody) TogglClient
    get(client_id: int | TogglClient) TogglClient | None
  }
  class Comparison {
    name
  }
  class CustomDecoder {
    MATCH_DICT : Final[dict[str, type[TogglClass]]]
    decode(obj: Any) Any
  }
  class CustomEncoder {
    default(obj: Any) Any
  }
  class DateTimeError {
  }
  class DetailedReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats, pagination: PaginationOptions | None) PaginatedResult[bytes]
    search_time_entries(body: ReportBody, pagination: PaginationOptions | None) PaginatedResult[list[dict[str, Any]]]
    totals_report(body: ReportBody) dict[str, int]
  }
  class Edits {
    failures : list[int]
    successes : list[int]
  }
  class InvalidExtensionError {
  }
  class JSONCache {
    cache_path
    parent
    session : JSONSession[T]
    add() None
    commit() None
    delete() None
    find(entry: T | dict[str, int]) T | None
    load() list[T]
    query() list[T]
    save(update: Iterable[T] | T, method: RequestMethod) None
    update() None
  }
  class JSONSession {
    data : list[T]
    max_length : int
    modified : int
    version : str
    commit(path: Path) None
    load(path: Path) None
    process_data(data: list[T]) list[T]
    refresh(path: Path) bool
  }
  class MissingParentError {
  }
  class NamingError {
  }
  class NoCacheAssignedError {
  }
  class OrganizationEndpoint {
    MODEL
    endpoint
    add(name: str, workspace_name: str) TogglOrganization
    collect() list[TogglOrganization]
    delete(organization: TogglOrganization | int) None
    edit(organization: TogglOrganization | int, name: str) TogglOrganization
    get(organization: TogglOrganization | int) TogglOrganization | None
  }
  class PaginatedResult {
    next_id : int | None
    next_row : int | None
    result : T
    next_options(page_size: int) PaginationOptions
  }
  class PaginationOptions {
    next_id : int | None
    next_row : int | None
    page_size : int
  }
  class ProjectBody {
    active : bool | Literal['both']
    client_id : int | None
    client_ids : list[int]
    client_name : str | None
    color : str | None
    end_date : date | None
    group_ids : list[int]
    is_private : bool | None
    name : str | None
    since : date | int | None
    start_date : date | None
    statuses : list[TogglProject.Status]
    user_ids : list[int]
    format(endpoint: str) dict[str, Any]
  }
  class ProjectEndpoint {
    BASIC_COLORS : Final[dict[str, str]]
    MODEL
    endpoint
    workspace_id
    add(body: ProjectBody) TogglProject
    collect(body: ProjectBody | None) list[TogglProject]
    delete(project: TogglProject | int) None
    edit(project: TogglProject | int, body: ProjectBody) TogglProject
    get(project_id: int | TogglProject) TogglProject | None
    get_color(name: str) str
    get_color_id(color: str) int
    status_to_query(status: TogglProject.Status) list[TogglQuery[Any]]
  }
  class ReportBody {
    client_ids : list[int | None]
    date_format : Literal['MM/DD/YYYY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'DD/MM/YYYY', 'DD.MM.YYYY']
    description : str | None
    duration_format : Literal['classic', 'decimal', 'improved']
    end_date : date | None
    enrich_response : bool
    group_ids : list[int]
    grouped : bool
    grouping : str | None
    include_time_entry_ids : bool
    max_duration_seconds : int | None
    min_duration_seconds : int | None
    order_by : Literal['title', 'duration'] | None
    order_dir : Literal['ASC', 'DESC'] | None
    project_ids : list[int | None]
    resolution : str | None
    rounding : int | None
    rounding_minutes : Literal[0, 1, 5, 6, 10, 12, 15, 30, 60, 240] | None
    start_date : date | None
    sub_grouping : str | None
    tag_ids : list[int | None]
    time_entry_ids : list[int]
    user_ids : list[int]
    format(endpoint: str) dict[str, Any]
  }
  class ReportEndpoint {
    BASE_ENDPOINT : ClassVar[str]
    workspace_id
    export_report(body: ReportBody)* Any
    search_time_entries(body: ReportBody)* Any
  }
  class RequestMethod {
    name
  }
  class SqliteCache {
    cache_path
    database
    metadata
    session
    add() None
    commit() None
    delete() None
    find(query: T | dict[str, Any]) T | None
    load() Query[T]
    query() Query[T]
    update() None
  }
  class Status {
    name
  }
  class SummaryReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats) bytes
    project_summaries(start_date: date | str, end_date: date | str) list[dict[str, int]]
    project_summary(project: TogglProject | int, start_date: date | str, end_date: date | str) dict[str, int]
    search_time_entries(body: ReportBody) list[dict[str, int]]
  }
  class TagEndpoint {
    MODEL
    endpoint
    workspace_id
    add(name: str) TogglTag
    collect() list[TogglTag]
    delete(tag: TogglTag | int) None
    edit(tag: TogglTag | int, name: str) TogglTag
    get(tag: TogglTag | int) TogglTag | None
  }
  class TogglAsyncCache {
    cache_path
    expire_after
    model
    parent
    add()* None
    delete()* None
    find(pk: int)* T | None
    find_method(method: RequestMethod) Callable[[Any], Awaitable[Any]] | None
    load()* Iterable[T]
    save(entry: list[T] | T, method: RequestMethod) None
    update()* None
  }
  class TogglAsyncCachedEndpoint {
    cache
    load_cache() Iterable[T]
    request(parameters: str, headers: Headers | None, body: dict[str, Any] | list[Any] | None, method: RequestMethod) T | list[T] | Response | None
    save_cache(response: list[T] | T, method: RequestMethod) None
  }
  class TogglAsyncEndpoint {
    BASE_ENDPOINT : ClassVar[URL]
    HEADERS : Final[Headers]
    MODEL : type[T] | None
    client
    re_raise : bool
    retries
    api_status() bool
    process_models(data: list[dict[str, Any]]) list[T]
    request(parameters: str, headers: Headers | None, body: dict[str, Any] | list[dict[str, Any]] | None, method: RequestMethod) T | list[T] | Response | None
  }
  class TogglCache {
    cache_path
    expire_after
    model
    parent
    add()* None
    commit()* None
    delete()* None
    find(entry: TC | dict[str, Any])* TC | None
    find_method(method: RequestMethod) CacheCallable[TC]
    load()* Iterable[TC]
    query()* Iterable[TC]
    save(entry: Iterable[TC] | TC, method: RequestMethod) None
    update()* None
  }
  class TogglCachedEndpoint {
    cache
    load_cache() Iterable[T]
    query() list[T]
    request(parameters: str, headers: Headers | None, body: dict[str, Any] | list[Any] | None, method: RequestMethod) T | list[T] | Response | None
    save_cache(response: list[T] | T, method: RequestMethod) None
  }
  class TogglClass {
    id : int
    name : str
    timestamp : datetime
    from_kwargs()* Self
  }
  class TogglClient {
    from_kwargs() TogglClient
  }
  class TogglEndpoint {
    BASE_ENDPOINT : ClassVar[str]
    HEADERS : Final[Headers]
    MODEL : type[T] | None
    client
    re_raise : bool
    retries
    api_status() bool
    process_models(data: list[dict[str, Any]]) list[T]
    request(parameters: str, headers: Headers | None, body: dict[str, Any] | list[dict[str, Any]] | None, method: RequestMethod) T | list[T] | Response | None
  }
  class TogglOrganization {
    from_kwargs() Self
    validate_name(name: str) None
  }
  class TogglProject {
    active : bool
    client : int | None
    color : str
    end_date : date | None
    start_date : date
    stop_date : date
    from_kwargs() TogglProject
    get_status() TogglProject.Status
  }
  class TogglQuery {
    comparison
    key : str
    value : T | Sequence[T]
  }
  class TogglTag {
    from_kwargs() TogglTag
  }
  class TogglTracker {
    duration : timedelta | None
    project : int | None
    start : datetime
    stop : datetime | str | None
    tags : list[TogglTag]
    from_kwargs() Self
    get_tags() list[TogglTag]
    running() bool
  }
  class TogglWorkspace {
    name : str
    organization : int
    from_kwargs() Self
    validate_name(name: str) None
  }
  class TrackerBody {
    created_with : str
    description : str | None
    duration : int | timedelta | None
    project_id : int | None
    shared_with_user_ids : list[int]
    start : datetime | None
    stop : datetime | None
    tag_action : Literal['add', 'remove'] | None
    tag_ids : list[int]
    tags : list[str]
    format(endpoint: str) dict[str, Any]
  }
  class TrackerEndpoint {
    MODEL
    TRACKER_ALREADY_STOPPED : Final[int]
    TRACKER_NOT_RUNNING : Final[int]
    endpoint
    workspace_id
    add(body: TrackerBody) TogglTracker
    bulk_edit() Edits
    collect(since: int | datetime | None, before: date | None, start_date: date | None, end_date: date | None) list[TogglTracker]
    current() TogglTracker | None
    delete(tracker: TogglTracker | int) None
    edit(tracker: TogglTracker | int, body: TrackerBody) TogglTracker
    get(tracker_id: int | TogglTracker) TogglTracker | None
    stop(tracker: TogglTracker | int) TogglTracker | None
  }
  class UTCDateTime {
    cache_ok : bool
    impl
    process_bind_param(value: datetime | None, _dialect: Dialect) datetime | None
    process_result_value(value: datetime | None, _dialect: Dialect) datetime | None
  }
  class User {
    name : str
    user_id : int
  }
  class UserEndpoint {
    get_details() dict[str, Any]
    verify_authentication(auth: BasicAuth) bool
  }
  class WeeklyReportEndpoint {
    endpoint
    export_report(body: ReportBody, extension: ReportFormats) bytes
    search_time_entries(body: ReportBody) list[dict[str, Any]]
  }
  class WorkspaceBody {
    admins : list[int]
    name : str | None
    only_admins_may_create_projects : bool
    only_admins_may_create_tags : bool
    only_admins_see_billable_rates : bool
    only_admins_see_team_dashboard : bool
    projects_billable_by_default : bool
    projects_enforce_billable : bool
    projects_private_by_default : bool
    rate_change_mode : Literal['start-today', 'override-current', 'override-all'] | None
    reports_collapse : bool
    rounding : int | None
    rounding_minutes : int | None
    format(endpoint: str) dict[str, Any]
  }
  class WorkspaceChild {
    workspace : int
    from_kwargs() Self
  }
  class WorkspaceEndpoint {
    MODEL
    organization_id
    add(body: WorkspaceBody) TogglWorkspace
    collect(since: datetime | int | None) list[TogglWorkspace]
    edit(workspace_id: TogglWorkspace | int, body: WorkspaceBody) TogglWorkspace
    get(workspace: TogglWorkspace | int) TogglWorkspace | None
    statistics(workspace_id: TogglWorkspace | int) WorkspaceStatistics
    tracker_constraints(workspace_id: TogglWorkspace | int) dict[str, bool]
  }
  class WorkspaceMissingError {
  }
  class WorkspaceStatistics {
    admins : list[User]
    groups_count : int
    members_count : int
  }
  ClientBody --|> BaseBody
  ClientEndpoint --|> TogglCachedEndpoint
  OrganizationEndpoint --|> TogglCachedEndpoint
  ProjectBody --|> BaseBody
  ProjectEndpoint --|> TogglCachedEndpoint
  TagEndpoint --|> TogglCachedEndpoint
  TrackerBody --|> BaseBody
  TrackerEndpoint --|> TogglCachedEndpoint
  UserEndpoint --|> TogglEndpoint
  WorkspaceBody --|> BaseBody
  WorkspaceEndpoint --|> TogglCachedEndpoint
  AsyncClientEndpoint --|> TogglAsyncCachedEndpoint
  TogglAsyncCachedEndpoint --|> TogglAsyncEndpoint
  AsyncOrganizationEndpoint --|> TogglAsyncCachedEndpoint
  AsyncProjectEndpoint --|> TogglAsyncCachedEndpoint
  AsyncDetailedReportEndpoint --|> AsyncReportEndpoint
  AsyncReportEndpoint --|> TogglAsyncEndpoint
  AsyncSummaryReportEndpoint --|> AsyncReportEndpoint
  AsyncWeeklyReportEndpoint --|> AsyncReportEndpoint
  AsyncSqliteCache --|> TogglAsyncCache
  AsyncTagEndpoint --|> TogglAsyncCachedEndpoint
  AsyncTrackerEndpoint --|> TogglAsyncCachedEndpoint
  AsyncUserEndpoint --|> TogglAsyncEndpoint
  AsyncWorkspaceEndpoint --|> TogglAsyncCachedEndpoint
  TogglCachedEndpoint --|> TogglEndpoint
  JSONCache --|> TogglCache
  SqliteCache --|> TogglCache
  TogglClient --|> WorkspaceChild
  TogglOrganization --|> TogglClass
  TogglProject --|> WorkspaceChild
  TogglTag --|> WorkspaceChild
  TogglTracker --|> WorkspaceChild
  TogglWorkspace --|> TogglClass
  WorkspaceChild --|> TogglClass
  DetailedReportEndpoint --|> ReportEndpoint
  ReportBody --|> BaseBody
  ReportEndpoint --|> TogglEndpoint
  SummaryReportEndpoint --|> ReportEndpoint
  WeeklyReportEndpoint --|> ReportEndpoint
  Comparison --* TogglQuery : comparison
  TogglClient --* ClientEndpoint : MODEL
  TogglClient --* AsyncClientEndpoint : MODEL
  TogglOrganization --* OrganizationEndpoint : MODEL
  TogglOrganization --* AsyncOrganizationEndpoint : MODEL
  TogglProject --* ProjectEndpoint : MODEL
  TogglProject --* AsyncProjectEndpoint : MODEL
  TogglTag --* TagEndpoint : MODEL
  TogglTag --* AsyncTagEndpoint : MODEL
  TogglTracker --* TrackerEndpoint : MODEL
  TogglTracker --* AsyncTrackerEndpoint : MODEL
  TogglWorkspace --* WorkspaceEndpoint : MODEL
  TogglWorkspace --* AsyncWorkspaceEndpoint : MODEL
Press "Alt" / "Option" to enable Pan & Zoom

Package Diagram

classDiagram
  class toggl_api {
  }
  class _client {
  }
  class _exceptions {
  }
  class _organization {
  }
  class _project {
  }
  class _tag {
  }
  class _tracker {
  }
  class _user {
  }
  class _utility {
  }
  class _version {
  }
  class _workspace {
  }
  class asyncio {
  }
  class _async_cache {
  }
  class _async_client {
  }
  class _async_endpoint {
  }
  class _async_organization {
  }
  class _async_project {
  }
  class _async_reports {
  }
  class _async_sqlite_cache {
  }
  class _async_tag {
  }
  class _async_tracker {
  }
  class _async_user {
  }
  class _async_workspace {
  }
  class config {
  }
  class meta {
  }
  class _base_endpoint {
  }
  class _body {
  }
  class _cached_endpoint {
  }
  class _enums {
  }
  class cache {
  }
  class _base_cache {
  }
  class _json_cache {
  }
  class _sqlite_cache {
  }
  class models {
  }
  class _decorators {
  }
  class _models {
  }
  class _schema {
  }
  class reports {
  }
  toggl_api --> _client
  toggl_api --> _exceptions
  toggl_api --> _organization
  toggl_api --> _project
  toggl_api --> _tag
  toggl_api --> _tracker
  toggl_api --> _user
  toggl_api --> _version
  toggl_api --> _workspace
  toggl_api --> models
  _client --> _exceptions
  _client --> meta
  _client --> cache
  _client --> models
  _organization --> meta
  _organization --> meta
  _organization --> models
  _project --> _exceptions
  _project --> _utility
  _project --> meta
  _project --> cache
  _project --> models
  _tag --> _exceptions
  _tag --> meta
  _tag --> cache
  _tag --> models
  _tracker --> _exceptions
  _tracker --> _utility
  _tracker --> meta
  _tracker --> cache
  _tracker --> models
  _user --> meta
  _workspace --> _exceptions
  _workspace --> _utility
  _workspace --> meta
  _workspace --> cache
  _workspace --> models
  asyncio --> _async_cache
  asyncio --> _async_client
  asyncio --> _async_endpoint
  asyncio --> _async_organization
  asyncio --> _async_project
  asyncio --> _async_reports
  asyncio --> _async_sqlite_cache
  asyncio --> _async_tag
  asyncio --> _async_tracker
  asyncio --> _async_user
  asyncio --> _async_workspace
  _async_cache --> _exceptions
  _async_cache --> _enums
  _async_cache --> models
  _async_client --> toggl_api
  _async_client --> _async_endpoint
  _async_client --> meta
  _async_endpoint --> _exceptions
  _async_endpoint --> meta
  _async_endpoint --> models
  _async_organization --> _async_endpoint
  _async_organization --> meta
  _async_organization --> models
  _async_project --> toggl_api
  _async_project --> _exceptions
  _async_project --> _async_endpoint
  _async_project --> meta
  _async_reports --> toggl_api
  _async_reports --> _utility
  _async_reports --> _async_endpoint
  _async_reports --> meta
  _async_reports --> reports
  _async_sqlite_cache --> _async_cache
  _async_sqlite_cache --> models
  _async_sqlite_cache --> _schema
  _async_tag --> toggl_api
  _async_tag --> _exceptions
  _async_tag --> _async_endpoint
  _async_tag --> meta
  _async_tracker --> toggl_api
  _async_tracker --> _exceptions
  _async_tracker --> _tracker
  _async_tracker --> _utility
  _async_tracker --> _async_endpoint
  _async_tracker --> meta
  _async_user --> _async_endpoint
  _async_workspace --> toggl_api
  _async_workspace --> _utility
  _async_workspace --> _async_endpoint
  _async_workspace --> meta
  meta --> _base_endpoint
  meta --> _body
  meta --> _cached_endpoint
  meta --> _enums
  _base_endpoint --> _enums
  _base_endpoint --> models
  _cached_endpoint --> _exceptions
  _cached_endpoint --> _base_endpoint
  _cached_endpoint --> _enums
  _cached_endpoint --> models
  cache --> _base_cache
  cache --> _json_cache
  cache --> _sqlite_cache
  _base_cache --> _exceptions
  _base_cache --> _enums
  _base_cache --> models
  _json_cache --> _utility
  _json_cache --> _version
  _json_cache --> _base_cache
  _json_cache --> models
  _sqlite_cache --> _utility
  _sqlite_cache --> _base_cache
  _sqlite_cache --> models
  _sqlite_cache --> _schema
  models --> _models
  models --> _schema
  _models --> _exceptions
  _models --> _utility
  _schema --> _utility
  _schema --> _decorators
  _schema --> _models
  reports --> _exceptions
  reports --> _utility
  reports --> meta
  reports --> models
  _client ..> cache
  _organization ..> cache
  _tracker ..> toggl_api
  _tracker ..> cache
  _workspace ..> toggl_api
  _async_cache ..> _async_endpoint
  _async_client ..> _async_sqlite_cache
  _async_endpoint ..> _async_sqlite_cache
  _async_organization ..> _async_sqlite_cache
  _async_project ..> _project
  _async_project ..> _async_sqlite_cache
  _async_sqlite_cache ..> _async_endpoint
  _async_tag ..> _async_sqlite_cache
  _async_tracker ..> _async_sqlite_cache
  _async_workspace ..> _async_sqlite_cache
  _cached_endpoint ..> _base_cache
  _base_cache ..> meta
  _json_cache ..> meta
  _sqlite_cache ..> meta
Press "Alt" / "Option" to enable Pan & Zoom