Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@
"python.terminal.activateEnvironment": true,
"pythonTestExplorer.testFramework": "pytest",
"pythonTestExplorer.testplanEnabled": false,
"testExplorer.useNativeTesting": true
"testExplorer.useNativeTesting": true,
"sonarlint.connectedMode.project": {
"connectionId": "tonkintaylor-sonarqub",
"projectKey": "tonkintaylor_templafy_433f7948-2868-4177-b69d-87f581ddd5ff"
}
}
263 changes: 162 additions & 101 deletions README.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions openapi-python-client-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project_name_override: templafy
package_name_override: templafy
package_version_override: 1.1.0
post_hooks:
- "ruff check . --fix"
- "ruff format ."
18 changes: 16 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ classifiers = [
]
dynamic = [ "urls", "version" ]
dependencies = [
"httpx>=0.24.0",
"pydantic>=2.0.0",
"attrs>=22.2.0",
"httpx>=0.23.0,<0.29.0",
"python-dateutil>=2.8.0",
"typing-extensions>=4.0.0",
]

[dependency-groups]
Expand Down Expand Up @@ -101,12 +103,14 @@ lint.ignore = [
"D107", # This is controversial, we don't always need docstrings for magic methods.
"D202", # This is controversial, it is useful to have a blank line after a docstring.
"D203", # This is controversial, no need to have a blank line before a docstring.
"D205", # 1 blank line required between summary line and description in docstring.
"D213", # This conflicts with D212 and violates PEP 257.
"D406", # This rule is for non-Google style docstrings.
"D407", # This rule is for non-Google style docstrings.
"D408", # This rule is for non-Google style docstrings.
"D409", # This rule is for non-Google style docstrings.
"D415", # Too excessive for our purposes (Docstring ending in punctuation).
"E501", # Line too long (ignored for flexibility).
"G004", # This is controversial, f-strings are too convenient to avoid.
"ISC001", # Incompatible with the ruff formatter.
# ##############################
Expand All @@ -118,6 +122,10 @@ lint.ignore = [
"PERF203", # Too many false positives.
"PERF401", # This can hurt readability; the performance is not always worth it.
"PIE804", # This is controversial, some pandas APIs work better with dict approach.
"PLR0911", # Too many return statements in function.
"PLR0912", # Too many branches in function.
"PLR0913", # Too many arguments in function definition.
"PLR0915", # Too many statements in function.
"PLR2004", # Too strict for exploratory work
"PLW2901", # Too many false positives.
"PT003", # Explicit is better than implicit
Expand All @@ -126,6 +134,7 @@ lint.ignore = [
"RET505", # This is controversial, returns within ``else`` are often clearer.
"RET506", # This is controversial, explicit branch structure is often clearer.
"S105", # Too many false positives.
"S110", # `try`-`except`-`pass` detected without logging.
"S311", # Too many false positives in a data science context.
"S324", # Too many false positives.
"S603", # Too many false positives.
Expand All @@ -137,6 +146,7 @@ lint.ignore = [
"TC003", # Too many false positives.
"TD", # These rules don't align well with the way we use TODOs.
"TD003", # Too excessive for our purposes (TODO Links).
"TRY300", # Consider moving statement to an `else` block.
"UP015", # This is controversial, explicit is better than implicit.
"UP040", # This doesn't integrate well with pydantic.
]
Expand Down Expand Up @@ -187,6 +197,10 @@ ignore-words-list = [ "..." ]
extend_exclude = [ "src/notebooks", "src/scripts", "src/archive" ]
experimental_namespace_package = true

[tool.deptry.per_rule_ignores]
DEP002 = [ "python-dateutil" ]
DEP003 = [ "typing_extensions" ]

[tool.pyproject-fmt]
keep_full_version = true

Expand Down
123 changes: 21 additions & 102 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# This file was autogenerated by uv via the following command:
# uv export --frozen --offline --no-default-groups -o=requirements.txt
-e .
annotated-types==0.7.0 \
--hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
--hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89
# via pydantic
anyio==4.10.0 \
--hash=sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6 \
--hash=sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1
anyio==4.11.0 \
--hash=sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc \
--hash=sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4
# via httpx
certifi==2025.7.14 \
--hash=sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2 \
--hash=sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995
attrs==25.3.0 \
--hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \
--hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b
# via templafy
certifi==2025.8.3 \
--hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \
--hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5
# via
# httpcore
# httpx
Expand All @@ -37,103 +37,22 @@ idna==3.10 \
# via
# anyio
# httpx
pydantic==2.11.7 \
--hash=sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db \
--hash=sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b
python-dateutil==2.9.0.post0 \
--hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \
--hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427
# via templafy
pydantic-core==2.33.2 \
--hash=sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d \
--hash=sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac \
--hash=sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02 \
--hash=sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56 \
--hash=sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22 \
--hash=sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef \
--hash=sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec \
--hash=sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d \
--hash=sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a \
--hash=sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f \
--hash=sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052 \
--hash=sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab \
--hash=sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916 \
--hash=sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c \
--hash=sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf \
--hash=sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a \
--hash=sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8 \
--hash=sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7 \
--hash=sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612 \
--hash=sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1 \
--hash=sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7 \
--hash=sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a \
--hash=sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b \
--hash=sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7 \
--hash=sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025 \
--hash=sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849 \
--hash=sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b \
--hash=sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa \
--hash=sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e \
--hash=sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea \
--hash=sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac \
--hash=sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51 \
--hash=sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e \
--hash=sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162 \
--hash=sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65 \
--hash=sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2 \
--hash=sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b \
--hash=sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de \
--hash=sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc \
--hash=sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb \
--hash=sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d \
--hash=sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef \
--hash=sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1 \
--hash=sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5 \
--hash=sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88 \
--hash=sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290 \
--hash=sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d \
--hash=sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808 \
--hash=sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc \
--hash=sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc \
--hash=sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e \
--hash=sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640 \
--hash=sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30 \
--hash=sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e \
--hash=sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9 \
--hash=sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9 \
--hash=sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f \
--hash=sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5 \
--hash=sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab \
--hash=sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572 \
--hash=sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593 \
--hash=sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29 \
--hash=sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1 \
--hash=sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f \
--hash=sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8 \
--hash=sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf \
--hash=sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246 \
--hash=sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9 \
--hash=sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011 \
--hash=sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a \
--hash=sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6 \
--hash=sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8 \
--hash=sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a \
--hash=sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2 \
--hash=sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c \
--hash=sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6 \
--hash=sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d
# via pydantic
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
--hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81
# via python-dateutil
sniffio==1.3.1 \
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc
# via anyio
typing-extensions==4.14.1 \
--hash=sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36 \
--hash=sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76
typing-extensions==4.15.0 \
--hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \
--hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
# via
# anyio
# exceptiongroup
# pydantic
# pydantic-core
# typing-inspection
typing-inspection==0.4.1 \
--hash=sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51 \
--hash=sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28
# via pydantic
# templafy
114 changes: 4 additions & 110 deletions src/templafy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,114 +1,8 @@
"""A Python client for the Templafy API."""
"""A client library for accessing Templafy Public API"""

# Trigger CI/CD to verify fixes
from .client import AuthenticatedClient, Client

from typing import Any

__version__ = "0.1.0"

# Type stubs for lazy-loaded items to satisfy pyright
# These will be overridden by __getattr__ at runtime
if False: # pragma: no cover
from . import api
from .client import AuthenticatedClient, Client
from .errors import (
AuthenticationError,
AuthorizationError,
NotFoundError,
RateLimitError,
ServerError,
TemplafyError,
UnexpectedStatusError,
ValidationError,
)

# Additional type declarations to satisfy pyright's __all__ checking
# These are only for type checking and will be replaced by __getattr__ at runtime
else:
# Client classes
AuthenticatedClient: type
Client: type

# Error classes
AuthenticationError: type
AuthorizationError: type
NotFoundError: type
RateLimitError: type
ServerError: type
TemplafyError: type
UnexpectedStatusError: type
ValidationError: type


# For now, defer imports that have external dependencies to avoid issues
# during development where dependencies may not be installed
def __getattr__(name: str) -> Any:
"""Lazy imports for components with external dependencies."""
if name == "Client":
from .client import Client # noqa: PLC0415

return Client
elif name == "AuthenticatedClient":
from .client import AuthenticatedClient # noqa: PLC0415

return AuthenticatedClient
elif name in [
"TemplafyError",
"AuthenticationError",
"AuthorizationError",
"NotFoundError",
"ValidationError",
"RateLimitError",
"ServerError",
"UnexpectedStatusError",
]:
from .errors import ( # noqa: PLC0415
AuthenticationError, # noqa: F401
AuthorizationError, # noqa: F401
NotFoundError, # noqa: F401
RateLimitError, # noqa: F401
ServerError, # noqa: F401
TemplafyError, # noqa: F401
UnexpectedStatusError, # noqa: F401
ValidationError, # noqa: F401
)

return locals()[name]
else:
error_message = f"module '{__name__}' has no attribute '{name}'"
raise AttributeError(error_message)


# Export models (these have no external dependencies)
from .models import ( # noqa: E402
Document,
Folder,
Image,
Library,
Link,
Slide,
Space,
Spreadsheet,
)

__all__ = [
__all__ = (
"AuthenticatedClient",
"AuthenticationError",
"AuthorizationError",
"Client",
"Document",
"Folder",
"Image",
"Library",
"Link",
"NotFoundError",
"RateLimitError",
"ServerError",
"Slide",
"Space",
"Spreadsheet",
"TemplafyError",
"UnexpectedStatusError",
"ValidationError",
"api",
]
)
16 changes: 1 addition & 15 deletions src/templafy/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
"""API endpoint modules for the Templafy API."""

# Re-export all API modules for easy importing
from . import documents, folders, images, libraries, links, slides, spaces, spreadsheets

__all__ = [
"documents",
"folders",
"images",
"libraries",
"links",
"slides",
"spaces",
"spreadsheets",
]
"""Contains methods for accessing the API"""
1 change: 1 addition & 0 deletions src/templafy/api/data_source_fields/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Contains endpoint functions for accessing the API"""
Loading
Loading