pycdoc 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycdoc-0.1.0/.github/workflows/build.yml +205 -0
- pycdoc-0.1.0/.gitignore +39 -0
- pycdoc-0.1.0/CHANGELOG.md +25 -0
- pycdoc-0.1.0/CMakeLists.txt +109 -0
- pycdoc-0.1.0/LICENSE +504 -0
- pycdoc-0.1.0/PKG-INFO +195 -0
- pycdoc-0.1.0/README.md +161 -0
- pycdoc-0.1.0/examples/create_cdoc.py +123 -0
- pycdoc-0.1.0/examples/create_cdoc_for_id.py +177 -0
- pycdoc-0.1.0/patches/libcdoc-python.patch +129 -0
- pycdoc-0.1.0/pyproject.toml +62 -0
- pycdoc-0.1.0/src/pycdoc/__init__.py +316 -0
- pycdoc-0.1.0/src/pycdoc/py.typed +0 -0
- pycdoc-0.1.0/swig/pycdoc.i +22 -0
- pycdoc-0.1.0/tests/__init__.py +0 -0
- pycdoc-0.1.0/tests/test_basic.py +307 -0
- pycdoc-0.1.0/tests/test_integration.py +326 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main, master]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build wheel
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
run: uv python install 3.12
|
|
24
|
+
|
|
25
|
+
- name: Clone libcdoc
|
|
26
|
+
run: git clone https://github.com/open-eid/libcdoc.git
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: |
|
|
30
|
+
sudo apt-get update
|
|
31
|
+
sudo apt-get install -y libssl-dev libxml2-dev zlib1g-dev flatbuffers-compiler libflatbuffers-dev
|
|
32
|
+
|
|
33
|
+
- name: Build wheel
|
|
34
|
+
run: uv build --wheel
|
|
35
|
+
|
|
36
|
+
- uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: wheel
|
|
39
|
+
path: dist/*.whl
|
|
40
|
+
|
|
41
|
+
test:
|
|
42
|
+
name: Test
|
|
43
|
+
needs: build
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- name: Install uv
|
|
50
|
+
uses: astral-sh/setup-uv@v5
|
|
51
|
+
|
|
52
|
+
- name: Set up Python
|
|
53
|
+
run: uv python install 3.12
|
|
54
|
+
|
|
55
|
+
- name: Download wheel
|
|
56
|
+
uses: actions/download-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: wheel
|
|
59
|
+
path: dist
|
|
60
|
+
|
|
61
|
+
- name: Install wheel and test
|
|
62
|
+
run: |
|
|
63
|
+
uv venv
|
|
64
|
+
uv pip install dist/*.whl pytest cryptography
|
|
65
|
+
uv run --no-project pytest tests/ -v
|
|
66
|
+
|
|
67
|
+
build_wheels:
|
|
68
|
+
name: Build wheels on ${{ matrix.os }}
|
|
69
|
+
runs-on: ${{ matrix.os }}
|
|
70
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
71
|
+
strategy:
|
|
72
|
+
fail-fast: false
|
|
73
|
+
matrix:
|
|
74
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
75
|
+
|
|
76
|
+
steps:
|
|
77
|
+
- uses: actions/checkout@v4
|
|
78
|
+
|
|
79
|
+
- name: Install uv
|
|
80
|
+
uses: astral-sh/setup-uv@v5
|
|
81
|
+
|
|
82
|
+
- name: Clone libcdoc
|
|
83
|
+
run: git clone https://github.com/open-eid/libcdoc.git
|
|
84
|
+
|
|
85
|
+
- name: Install dependencies (Ubuntu)
|
|
86
|
+
if: runner.os == 'Linux'
|
|
87
|
+
run: |
|
|
88
|
+
sudo apt-get update
|
|
89
|
+
sudo apt-get install -y libssl-dev libxml2-dev zlib1g-dev
|
|
90
|
+
|
|
91
|
+
- name: Install dependencies (macOS)
|
|
92
|
+
if: runner.os == 'macOS'
|
|
93
|
+
run: |
|
|
94
|
+
brew install openssl@3 libxml2 flatbuffers cmake swig
|
|
95
|
+
|
|
96
|
+
- name: Install dependencies (Windows)
|
|
97
|
+
if: runner.os == 'Windows'
|
|
98
|
+
run: |
|
|
99
|
+
vcpkg install openssl:x64-windows zlib:x64-windows libxml2:x64-windows flatbuffers:x64-windows
|
|
100
|
+
|
|
101
|
+
- name: Build wheels
|
|
102
|
+
uses: pypa/cibuildwheel@v2.22.0
|
|
103
|
+
env:
|
|
104
|
+
# Use uv for faster builds
|
|
105
|
+
CIBW_BUILD_FRONTEND: "build[uv]"
|
|
106
|
+
# Build for Python 3.9-3.13
|
|
107
|
+
CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
|
|
108
|
+
# Skip 32-bit builds and musllinux
|
|
109
|
+
CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux_*"
|
|
110
|
+
# Use manylinux_2_28 for GCC 13 (C++23 support)
|
|
111
|
+
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
|
|
112
|
+
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
|
|
113
|
+
# Install build dependencies in the container (need GCC 13 for C++23, OpenSSL 3.x)
|
|
114
|
+
CIBW_BEFORE_ALL_LINUX: >
|
|
115
|
+
dnf install -y gcc-toolset-13 perl-IPC-Cmd libxml2-devel zlib-devel &&
|
|
116
|
+
curl -L https://www.openssl.org/source/openssl-3.0.13.tar.gz | tar xz &&
|
|
117
|
+
cd openssl-3.0.13 &&
|
|
118
|
+
source /opt/rh/gcc-toolset-13/enable &&
|
|
119
|
+
./config --prefix=/usr/local/openssl3 --openssldir=/usr/local/openssl3 &&
|
|
120
|
+
make -j$(nproc) &&
|
|
121
|
+
make install_sw install_ssldirs
|
|
122
|
+
CIBW_ENVIRONMENT_LINUX: >
|
|
123
|
+
OPENSSL_ROOT_DIR=/usr/local/openssl3
|
|
124
|
+
PKG_CONFIG_PATH=/usr/local/openssl3/lib64/pkgconfig
|
|
125
|
+
PATH=/opt/rh/gcc-toolset-13/root/usr/bin:$PATH
|
|
126
|
+
LD_LIBRARY_PATH=/usr/local/openssl3/lib64:/usr/local/openssl3/lib:/opt/rh/gcc-toolset-13/root/usr/lib64:$LD_LIBRARY_PATH
|
|
127
|
+
# Install flatbuffers from source on Linux
|
|
128
|
+
CIBW_BEFORE_BUILD_LINUX: >
|
|
129
|
+
uv pip install --system cmake swig &&
|
|
130
|
+
if ! command -v flatc; then
|
|
131
|
+
cd /tmp &&
|
|
132
|
+
curl -L https://github.com/google/flatbuffers/archive/refs/tags/v24.3.25.tar.gz | tar xz &&
|
|
133
|
+
cd flatbuffers-24.3.25 &&
|
|
134
|
+
cmake -B build -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF &&
|
|
135
|
+
cmake --build build --target install;
|
|
136
|
+
fi
|
|
137
|
+
# cmake and swig installed via brew in Install dependencies step
|
|
138
|
+
CIBW_BEFORE_BUILD_WINDOWS: uv pip install --system cmake swig delvewheel
|
|
139
|
+
# Set vcpkg toolchain for Windows
|
|
140
|
+
CIBW_ENVIRONMENT_WINDOWS: >
|
|
141
|
+
CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
|
142
|
+
# Set OpenSSL path on macOS; Homebrew OpenSSL requires macOS 15+
|
|
143
|
+
CIBW_ENVIRONMENT_MACOS: >
|
|
144
|
+
OPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl@3
|
|
145
|
+
CMAKE_PREFIX_PATH=/opt/homebrew
|
|
146
|
+
MACOSX_DEPLOYMENT_TARGET=15.0
|
|
147
|
+
# Repair wheels (bundle native dependencies)
|
|
148
|
+
CIBW_REPAIR_WHEEL_COMMAND_LINUX: auditwheel repair -w {dest_dir} {wheel}
|
|
149
|
+
CIBW_REPAIR_WHEEL_COMMAND_MACOS: delocate-wheel -w {dest_dir} {wheel}
|
|
150
|
+
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: delvewheel repair --add-path C:/vcpkg/installed/x64-windows/bin -w {dest_dir} {wheel}
|
|
151
|
+
# Test the wheel
|
|
152
|
+
CIBW_TEST_REQUIRES: pytest
|
|
153
|
+
CIBW_TEST_COMMAND: pytest {project}/tests -v
|
|
154
|
+
|
|
155
|
+
- uses: actions/upload-artifact@v4
|
|
156
|
+
with:
|
|
157
|
+
name: wheels-${{ matrix.os }}
|
|
158
|
+
path: ./wheelhouse/*.whl
|
|
159
|
+
|
|
160
|
+
build_sdist:
|
|
161
|
+
name: Build source distribution
|
|
162
|
+
runs-on: ubuntu-latest
|
|
163
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
164
|
+
steps:
|
|
165
|
+
- uses: actions/checkout@v4
|
|
166
|
+
|
|
167
|
+
- name: Install uv
|
|
168
|
+
uses: astral-sh/setup-uv@v5
|
|
169
|
+
|
|
170
|
+
- name: Clone libcdoc
|
|
171
|
+
run: git clone https://github.com/open-eid/libcdoc.git
|
|
172
|
+
|
|
173
|
+
- name: Build sdist
|
|
174
|
+
run: uv build --sdist
|
|
175
|
+
|
|
176
|
+
- uses: actions/upload-artifact@v4
|
|
177
|
+
with:
|
|
178
|
+
name: sdist
|
|
179
|
+
path: dist/*.tar.gz
|
|
180
|
+
|
|
181
|
+
publish:
|
|
182
|
+
name: Publish to PyPI
|
|
183
|
+
needs: [build_wheels, build_sdist]
|
|
184
|
+
runs-on: ubuntu-latest
|
|
185
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
186
|
+
environment:
|
|
187
|
+
name: pypi
|
|
188
|
+
url: https://pypi.org/p/pycdoc
|
|
189
|
+
permissions:
|
|
190
|
+
id-token: write
|
|
191
|
+
|
|
192
|
+
steps:
|
|
193
|
+
- uses: actions/download-artifact@v4
|
|
194
|
+
with:
|
|
195
|
+
pattern: wheels-*
|
|
196
|
+
path: dist
|
|
197
|
+
merge-multiple: true
|
|
198
|
+
|
|
199
|
+
- uses: actions/download-artifact@v4
|
|
200
|
+
with:
|
|
201
|
+
name: sdist
|
|
202
|
+
path: dist
|
|
203
|
+
|
|
204
|
+
- name: Publish to PyPI
|
|
205
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
pycdoc-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Build directories
|
|
2
|
+
build/
|
|
3
|
+
dist/
|
|
4
|
+
*.egg-info/
|
|
5
|
+
wheelhouse/
|
|
6
|
+
|
|
7
|
+
# Python bytecode
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
*$py.class
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
test-env/
|
|
17
|
+
|
|
18
|
+
# IDE
|
|
19
|
+
.idea/
|
|
20
|
+
.vscode/
|
|
21
|
+
*.swp
|
|
22
|
+
*.swo
|
|
23
|
+
*~
|
|
24
|
+
|
|
25
|
+
# OS
|
|
26
|
+
.DS_Store
|
|
27
|
+
Thumbs.db
|
|
28
|
+
|
|
29
|
+
# Upstream library (clone separately with: git clone https://github.com/open-eid/libcdoc.git)
|
|
30
|
+
libcdoc/
|
|
31
|
+
|
|
32
|
+
# Claude Code
|
|
33
|
+
.claude/
|
|
34
|
+
|
|
35
|
+
# Test artifacts
|
|
36
|
+
*.cdoc
|
|
37
|
+
|
|
38
|
+
# Lock files (library - not committed)
|
|
39
|
+
uv.lock
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2025-02-09
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- Python bindings for libcdoc using SWIG
|
|
13
|
+
- Support for reading and writing CDOC 1.0 and CDOC 2.0 containers
|
|
14
|
+
- High-level `encrypt()` function for encrypting files by Estonian personal ID code
|
|
15
|
+
- Automatic certificate lookup from SK LDAP (`esteid.ldap.sk.ee`)
|
|
16
|
+
- Support for encrypting single files, multiple files, or raw bytes
|
|
17
|
+
- Optional `ldap` extra for certificate lookup (`pip install pycdoc[ldap]`)
|
|
18
|
+
- `CDocReader` and `CDocWriter` classes
|
|
19
|
+
- Configuration classes: `Configuration`, `JSONConfiguration`
|
|
20
|
+
- Backend classes: `CryptoBackend`, `NetworkBackend`, `PKCS11Backend`
|
|
21
|
+
- Data types: `Recipient`, `Lock`, `FileInfo`, `DataSource`, `DataConsumer`
|
|
22
|
+
- Error codes and `get_error_str()` function
|
|
23
|
+
- Example scripts for creating CDOC containers
|
|
24
|
+
- CI/CD workflow with cibuildwheel for multi-platform builds
|
|
25
|
+
- macOS arm64 wheel support
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.18)
|
|
2
|
+
project(pycdoc VERSION 0.1.0 LANGUAGES C CXX)
|
|
3
|
+
|
|
4
|
+
set(CMAKE_CXX_STANDARD 23)
|
|
5
|
+
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
|
6
|
+
|
|
7
|
+
# Apply Python SWIG bindings patch to libcdoc
|
|
8
|
+
# This adds Python-specific typemaps and fixes LockVector template ordering
|
|
9
|
+
find_program(PATCH_EXECUTABLE patch)
|
|
10
|
+
if(PATCH_EXECUTABLE)
|
|
11
|
+
execute_process(
|
|
12
|
+
COMMAND ${PATCH_EXECUTABLE} -p1 --forward -i ${CMAKE_CURRENT_SOURCE_DIR}/patches/libcdoc-python.patch
|
|
13
|
+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libcdoc
|
|
14
|
+
RESULT_VARIABLE PATCH_RESULT
|
|
15
|
+
OUTPUT_QUIET
|
|
16
|
+
ERROR_QUIET
|
|
17
|
+
)
|
|
18
|
+
# Result 0 = success, 1 = already applied (which is fine)
|
|
19
|
+
if(PATCH_RESULT GREATER 1)
|
|
20
|
+
message(WARNING "Failed to apply libcdoc-python.patch (error ${PATCH_RESULT})")
|
|
21
|
+
endif()
|
|
22
|
+
else()
|
|
23
|
+
message(FATAL_ERROR "patch executable not found - required to build Python bindings")
|
|
24
|
+
endif()
|
|
25
|
+
|
|
26
|
+
# Find required packages
|
|
27
|
+
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
|
|
28
|
+
find_package(SWIG 4.0 REQUIRED)
|
|
29
|
+
include(${SWIG_USE_FILE})
|
|
30
|
+
|
|
31
|
+
# Configure libcdoc build options - disable SWIG in libcdoc, we build it ourselves
|
|
32
|
+
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build static library" FORCE)
|
|
33
|
+
set(FRAMEWORK OFF CACHE BOOL "Disable framework build" FORCE)
|
|
34
|
+
set(BUILD_TOOLS OFF CACHE BOOL "Don't build cdoc-tool" FORCE)
|
|
35
|
+
set(LIBCDOC_WITH_DOCS OFF CACHE BOOL "Don't build docs" FORCE)
|
|
36
|
+
|
|
37
|
+
# Prevent libcdoc from finding SWIG - we handle SWIG bindings ourselves
|
|
38
|
+
set(CMAKE_DISABLE_FIND_PACKAGE_SWIG TRUE)
|
|
39
|
+
|
|
40
|
+
# Add libcdoc as subdirectory
|
|
41
|
+
add_subdirectory(libcdoc)
|
|
42
|
+
|
|
43
|
+
set(CMAKE_DISABLE_FIND_PACKAGE_SWIG FALSE)
|
|
44
|
+
|
|
45
|
+
# Set up SWIG for Python using our custom wrapper that adds Python-specific
|
|
46
|
+
# template instantiations (ByteVector, StringVector, etc.) and director support
|
|
47
|
+
set(PYCDOC_SWIG_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/swig/pycdoc.i)
|
|
48
|
+
set(CMAKE_SWIG_FLAGS "")
|
|
49
|
+
set_property(SOURCE ${PYCDOC_SWIG_SOURCE} PROPERTY CPLUSPLUS ON)
|
|
50
|
+
set_property(SOURCE ${PYCDOC_SWIG_SOURCE} PROPERTY SWIG_MODULE_NAME libcdoc)
|
|
51
|
+
# Set SWIG include directories - need both libcdoc/ (for libcdoc.i) and libcdoc/cdoc/ (for headers)
|
|
52
|
+
set_property(SOURCE ${PYCDOC_SWIG_SOURCE}
|
|
53
|
+
PROPERTY INCLUDE_DIRECTORIES
|
|
54
|
+
${CMAKE_CURRENT_SOURCE_DIR}/libcdoc
|
|
55
|
+
${CMAKE_CURRENT_SOURCE_DIR}/libcdoc/cdoc)
|
|
56
|
+
|
|
57
|
+
# Create the Python extension
|
|
58
|
+
swig_add_library(pycdoc_swig
|
|
59
|
+
TYPE MODULE
|
|
60
|
+
LANGUAGE python
|
|
61
|
+
OUTPUT_DIR ${CMAKE_BINARY_DIR}/pycdoc
|
|
62
|
+
SOURCES ${PYCDOC_SWIG_SOURCE}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Include directories for C++ compilation
|
|
66
|
+
target_include_directories(pycdoc_swig PRIVATE
|
|
67
|
+
${CMAKE_CURRENT_SOURCE_DIR}/libcdoc/cdoc
|
|
68
|
+
${Python3_INCLUDE_DIRS}
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Set output name to _libcdoc (SWIG convention: _<module_name>)
|
|
72
|
+
set_target_properties(pycdoc_swig PROPERTIES
|
|
73
|
+
OUTPUT_NAME "_libcdoc"
|
|
74
|
+
PREFIX ""
|
|
75
|
+
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/pycdoc
|
|
76
|
+
SWIG_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/libcdoc;${CMAKE_CURRENT_SOURCE_DIR}/libcdoc/cdoc"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Link against cdoc and Python
|
|
80
|
+
target_link_libraries(pycdoc_swig PRIVATE
|
|
81
|
+
cdoc
|
|
82
|
+
Python3::Module
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# On macOS, handle rpath for finding libraries
|
|
86
|
+
if(APPLE)
|
|
87
|
+
set_target_properties(pycdoc_swig PROPERTIES
|
|
88
|
+
INSTALL_RPATH "@loader_path"
|
|
89
|
+
BUILD_WITH_INSTALL_RPATH TRUE
|
|
90
|
+
)
|
|
91
|
+
endif()
|
|
92
|
+
|
|
93
|
+
# Install targets for scikit-build-core
|
|
94
|
+
# The wheel.install-dir in pyproject.toml is set to "pycdoc"
|
|
95
|
+
# so we install relative to that
|
|
96
|
+
install(TARGETS pycdoc_swig
|
|
97
|
+
LIBRARY DESTINATION .
|
|
98
|
+
RUNTIME DESTINATION .
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Install the SWIG-generated Python wrapper (libcdoc.py)
|
|
102
|
+
install(FILES ${CMAKE_BINARY_DIR}/pycdoc/libcdoc.py
|
|
103
|
+
DESTINATION .
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Install the package __init__.py
|
|
107
|
+
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pycdoc/__init__.py
|
|
108
|
+
DESTINATION .
|
|
109
|
+
)
|