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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/openapi-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
project_name_override: templafy
package_name_override: templafy
literal_enums: true
generate_all_tags: true
post_hooks:
- "ruff check src/templafy --fix"
- "ruff format src/templafy"
field_prefix: attr_
content_type_overrides:
application/vnd.openxmlformats-officedocument.wordprocessingml.document: application/octet-stream
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet: application/octet-stream
application/vnd.openxmlformats-officedocument.presentationml.presentation: application/octet-stream
153 changes: 120 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,145 @@
# Python PyPI Package Template
# Templafy API Client

https://api.templafy.com/
A Python client for the Templafy API using openapi-python-client for type-safe, modern Python API access.

A minimal template for creating Python packages with a simple "Hello World" example.
## Overview

This package provides a Python client for the Templafy API, allowing you to programmatically access templates, documents, images, and other assets in your Templafy workspace.

## Installation

```bash
pip install -e .
```

## Quick Start

### 1. Use this template
### Basic Usage

```python
from templafy import AuthenticatedClient
from templafy.api import spaces, documents

# Initialize client
client = AuthenticatedClient(
base_url="https://your-tenant.api.templafy.com/v3",
token="your-api-token"
)

# Use with context manager (recommended)
with client as client:
# List all spaces
all_spaces = spaces.get_spaces(client=client)
print(f"Found {len(all_spaces)} spaces")

# List documents
all_documents = documents.get_documents(client=client)
print(f"Found {len(all_documents)} documents")
```

Click the "Use this template" button on GitHub to create your own repository:
### Available API Endpoints

### 2. Install dependencies
The client provides access to the following Templafy API resources:

```bash
# Run the development setup script
.\tasks\dev_sync.ps1
- **Spaces** - Workspace/tenant management
- **Libraries** - Library management across spaces
- **Documents** - Document template operations and generation
- **Folders** - Folder structure management
- **Images** - Image asset management
- **Slides** - PowerPoint slide management
- **Spreadsheets** - Excel template operations
- **Links** - Link asset management

### Models

The client includes type-safe models for all API resources:

```python
from templafy import Space, Document, Library, Image

# Models are automatically used when calling API methods
spaces = spaces.get_spaces(client=client)
for space in spaces:
print(f"Space: {space.name} (ID: {space.id})")
```

### 3. Customize the package
## API Structure

#### Rename the package
```
templafy/
├── client.py # Base Client and AuthenticatedClient classes
├── models/ # Type-safe models for all schemas
│ ├── space.py # Space-related models
│ ├── document.py # Document-related models
│ ├── library.py # Library-related models
│ └── ...
├── api/ # API endpoint modules by resource
│ ├── spaces.py # Spaces API endpoints
│ ├── documents.py # Documents API endpoints
│ ├── libraries.py # Libraries API endpoints
│ └── ...
├── types.py # Common type definitions
└── errors.py # Error classes and exceptions
```

1. Rename directories:
```bash
mv src/whitelabel src/YOUR_PACKAGE_NAME
mv tests/whitelabel tests/YOUR_PACKAGE_NAME
```
## Error Handling

The client provides specific error classes for different types of API errors:

```python
from templafy.errors import (
AuthenticationError,
AuthorizationError,
NotFoundError,
ValidationError,
RateLimitError,
ServerError
)

try:
documents = documents.get_documents(client=client)
except AuthenticationError:
print("API token is invalid")
except AuthorizationError:
print("Insufficient permissions")
except NotFoundError:
print("Resource not found")
except RateLimitError:
print("Rate limit exceeded")
```

2. Update `pyproject.toml`:
- Change `name = "whitelabel"` to `name = "YOUR_PACKAGE_NAME"`
- Update author information
- Update repository URLs
## Development

3. Update import statements in your code from `whitelabel` to `YOUR_PACKAGE_NAME`
### Dependencies

This project requires Python 3.12+ and the following dependencies:

## Next Steps
- `httpx` - HTTP client
- `pydantic` - Data validation and settings management
- `typing-extensions` - Additional typing features

1. Replace the hello_world function with your own code
2. Add your functions to `src/YOUR_PACKAGE_NAME/functions/`
3. Write tests in `tests/YOUR_PACKAGE_NAME/`
4. Update `pyproject.toml` with your package details
### Testing

## CI/CD Configuration
```bash
python -m pytest tests/ -v
```

### Code Quality

### SonarQube Setup
The project uses `ruff` for linting and formatting:

To enable SonarQube analysis in your CI/CD pipeline, set the following variables:
```bash
ruff check src/templafy --fix
ruff format src/templafy
```

- `SONAR_TOKEN`: Set as a **secret** in your CI/CD platform (authentication token for SonarQube)
- `SONAR_PROJECT_KEY`: Set as an **environment variable** in your CI/CD pipeline (unique key for your project, e.g., `your-org_your-repo`)
## Contributing

`SONAR_HOST_URL` is typically configured at the organization level.
1. Install development dependencies
2. Make your changes
3. Run tests and linting
4. Submit a pull request

## License

MIT License
MIT License - see LICENSE file for details.
18 changes: 9 additions & 9 deletions assets/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -810,7 +810,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -1776,7 +1776,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -2838,7 +2838,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -3439,7 +3439,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -3973,7 +3973,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -4507,7 +4507,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -5119,7 +5119,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down Expand Up @@ -5713,7 +5713,7 @@
},
"Name": {
"type": "string",
"description": "The name is inferred from the file name by default. It can be overriden by providing a different value with this field"
"description": "The name is inferred from the file name by default. It can be overridden by providing a different value with this field"
},
"Description": {
"type": "string",
Expand Down
12 changes: 8 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ requires = [
]

[project]
name = "whitelabel"
description = "A minimal Python package template with a simple Hello World example."
name = "templafy"
description = "A Python client for the Templafy API using openapi-python-client."
readme = "README.md"
license = "MIT"
license-files = [ "LICENSE" ]
Expand All @@ -33,7 +33,10 @@ classifiers = [
"Programming Language :: Python :: 3.13",
]
dynamic = [ "urls", "version" ]
dependencies = [ ]
dependencies = [
"httpx>=0.24.0",
"pydantic>=2.0.0",
]

[dependency-groups]
dev = [
Expand All @@ -44,6 +47,7 @@ dev = [
"ipywidgets>=8.1.7",
"matplotlib>=3.10.3",
"nbstripout>=0.8.1",
"openapi-python-client>=0.15.0",
"perfplot>=0.10.2",
"pip>=25.1.1",
"pre-commit>=4.2.0",
Expand Down Expand Up @@ -74,7 +78,7 @@ source = "vcs"
"Source Archive" = "https://github.com/tonkintaylor/YOUR_REPOSITORY/archive/{commit_hash}.zip"

[tool.hatch.build.hooks.vcs]
version-file = "src/whitelabel/_version.py"
version-file = "src/templafy/_version.py"

[tool.ruff]
line-length = 88
Expand Down
2 changes: 1 addition & 1 deletion src/whitelabel/AGENTS.md → src/templafy/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

## PeerTube API

- We are wrapping the PeerTube API that adheres to the OpenAPI 3 standard.
- We are wrapping the Templafy API that adheres to the OpenAPI 3 standard.
- The JSON specification file can be found in `assets\openapi.json`.
- All API endpoints information is contained there.
- Note that the file might contain typos; do not correct them in the original JSON file, but correct them when using the text in the wrappers.
Expand Down
Loading
Loading