Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
82 changes: 82 additions & 0 deletions .github/workflows/documentation-upload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Generate and upload documentation

on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to use for the documentation package in semver format (e.g. 1.2.3)'
required: true

jobs:
upload-documentation:
runs-on: ubuntu-latest
env:
SDK_NAME: sinch-sdk-python

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Resolve Version
id: version
run: |
if [ "${{ github.event_name }}" = "release" ]; then
VERSION="${{ github.event.release.tag_name }}"
else
VERSION="${{ inputs.version }}"
fi
# Strip leading 'v' if present (e.g. v1.2.3 → 1.2.3)
VERSION="${VERSION#v}"
echo "value=${VERSION}" >> "$GITHUB_OUTPUT"

- name: Validate Version Format
run: |
VERSION="${{ steps.version.outputs.value }}"
SEMVER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((alpha|beta|preview)(\.[0-9]+)?))?$'
if [[ ! "$VERSION" =~ $SEMVER_REGEX ]]; then
echo "::error::Invalid version format: '$VERSION'. Expected semver (e.g. 1.2.3, 1.2.3-alpha, 1.2.3-beta.1, 1.2.3-preview)"
exit 1
fi
echo "Version '$VERSION' is valid"

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install dev dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Generate Documentation
run: |
make docs

- name: Package Documentation
run: |
cd docs/build/html
zip -r "../../../${{ env.SDK_NAME }}-${{ steps.version.outputs.value }}.zip" .

- name: Upload to GitLab Registry
run: |
echo "Uploading documentation package to GitLab Registry..."
VERSION="${{ steps.version.outputs.value }}"
curl --fail --show-error --location --header "PRIVATE-TOKEN: ${{ secrets.GITLAB_REGISTRY_UPLOAD_DOC_TOKEN }}" \
--upload-file "./${{ env.SDK_NAME }}-${VERSION}.zip" \
"https://gitlab.com/api/v4/projects/63164411/packages/generic/${{ env.SDK_NAME }}/${VERSION}/${{ env.SDK_NAME }}-${VERSION}.zip"
echo "Documentation package for version ${VERSION} uploaded to GitLab Registry"

- name: Trigger Downstream GitLab Pipeline
run: |
echo "Triggering downstream GitLab pipeline to notify about new documentation package version..."
VERSION="${{ steps.version.outputs.value }}"
curl --fail --show-error --location --request POST \
--form "token=${{ secrets.GITLAB_NOTIFY_REGISTRY_UPLOADED_DOC_TOKEN }}" \
--form "ref=main" \
--form "variables[UPSTREAM_PACKAGE_NAME]=${{ env.SDK_NAME }}" \
--form "variables[UPSTREAM_PACKAGE_VERSION]=${VERSION}" \
"https://gitlab.com/api/v4/projects/63164411/trigger/pipeline"
echo "Documentation repo notified about new package version ${VERSION}"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ instance/
.scrapy

# Sphinx documentation
docs/_build/
docs/build/
docs/api/


# PyBuilder
.pybuilder/
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONY: docs

docs:
rm -rf docs/build
rm -rf docs/api
sphinx-apidoc --force --separate --no-toc --maxdepth 2 --templatedir docs/_templates/apidoc -o docs/api sinch
sphinx-build -b html docs docs/build/html
21 changes: 21 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/* ---------------------------------------------------------------------------
Multi-line signatures (one parameter per line).

When a signature is wrapped, Sphinx renders each parameter as a <dd> inside
a nested <dl>. The Read the Docs theme styles every <dl>/<dd> with borders,
background tint and vertical margins, which leak into the signature and draw
ugly "lines" between parameters. Flatten that nested list so the parameters
read as a clean indented column.
--------------------------------------------------------------------------- */
.rst-content .sig dl,
.rst-content .sig dd {
margin: 0;
padding: 0;
border: none;
background: none;
}

/* Keep each parameter indented under the opening parenthesis. */
.rst-content .sig dd {
margin-left: 2em;
}
8 changes: 8 additions & 0 deletions docs/_templates/apidoc/module.rst.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{%- if show_headings %}
{{- [basename, "module"] | join(" ") | e | heading }}

{% endif -%}
.. automodule:: {{ qualname }}
{%- for option in automodule_options %}
:{{ option }}:
{%- endfor %}
35 changes: 35 additions & 0 deletions docs/_templates/apidoc/package.rst.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{%- macro automodule(modname, options) -%}
.. automodule:: {{ modname }}
{%- for option in options %}
:{{ option }}:
{%- endfor %}
{%- endmacro %}

{%- macro toctree(docnames) -%}
.. toctree::
:maxdepth: {{ maxdepth }}
{% for docname in docnames %}
{{ docname }}
{%- endfor %}
{%- endmacro %}

{{- [pkgname, "package"] | join(" ") | e | heading }}

{%- if is_namespace %}
.. py:module:: {{ pkgname }}
{% endif %}

{%- if subpackages %}
{{ toctree(subpackages) }}
{% endif %}

{%- if submodules %}
{% if separatemodules %}
{{ toctree(submodules) }}
{% else %}
{% for submodule in submodules %}
{{ [submodule.split(".")[-1], "module"] | join(" ") | e | heading(2) }}
{{ automodule(submodule, automodule_options) }}
{% endfor %}
{%- endif %}
{%- endif %}
62 changes: 62 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os
import sys

# Allow autodoc to import the sinch package from the project root
sys.path.insert(0, os.path.abspath(".."))
from sinch import __version__

# -- Project information -------------------------------------------------------

project = "Sinch Python SDK"
copyright = "2026, Sinch Developer Experience Team"
author = "Sinch Developer Experience Team"
release = __version__

# -- General configuration -----------------------------------------------------

extensions = [
# Pulls docstrings from Python source into the generated .rst files
"sphinx.ext.autodoc",
# Adds [source] links that open the highlighted source file
"sphinx.ext.viewcode",
]

# The .rst files under api/ are generated by the `sphinx-apidoc` CLI invoked
# from the Makefile (`make docs`), using the custom templates in
# _templates/apidoc/ to strip the "package" suffix and the
# "Subpackages"/"Submodules"/"Module contents" headings. The
# sphinx.ext.apidoc extension is intentionally NOT used because it ignores
# the template directory.

# -- sphinx.ext.autodoc --------------------------------------------------------

autodoc_default_options = {
# Document all public members (methods, attributes, nested classes)
"members": True,
'undoc-members': True,
# Show the class inheritance chain
"show-inheritance": True,
# Preserve the order in which members appear in the source file
"member-order": "bysource",
}

# Render type hints as part of the parameter/return descriptions, not the signature
autodoc_typehints = "both"
python_maximum_signature_line_length = 88

# -- HTML output ---------------------------------------------------------------

html_theme = "sphinx_rtd_theme"

html_theme_options = {
# Maximum depth of the navigation sidebar (-1 = unlimited)
"navigation_depth": -1,
# Keep all navigation entries expanded by default
"collapse_navigation": False,
}

# Directory with extra static files (custom CSS, etc.), relative to this conf.py
html_static_path = ["_static"]

# Extra stylesheets loaded after the theme's own CSS
html_css_files = ["custom.css"]
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Sinch Python SDK
================

.. toctree::
:maxdepth: 3
:caption: API Reference

api/sinch
7 changes: 6 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ ruff
requests

# Data Validation
pydantic >= 2.0.0
pydantic >= 2.0.0

# Documentation
# Sphinx 7.1 introduced python_maximum_signature_line_length and 7.x is also the last series supporting Python 3.9.
sphinx >= 7.1
sphinx-rtd-theme >= 2.0
Empty file.
Empty file.
Empty file.
Loading