Skip to content

Commit a735205

Browse files
committed
Python API
0 parents  commit a735205

15 files changed

Lines changed: 1318 additions & 0 deletions

.github/workflows/build.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
tags:
8+
- "v*"
9+
10+
11+
jobs:
12+
windows-build:
13+
runs-on: windows-latest
14+
strategy:
15+
matrix:
16+
python-versions: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Clone FaceSDK
22+
uses: actions/checkout@v4
23+
with:
24+
repository: 3DiVi/face-sdk
25+
path: FaceSDK
26+
27+
- name: Remove other files from FaceSDK
28+
shell: bash
29+
working-directory: FaceSDK
30+
run: |
31+
mv include ../includeFaceSDK
32+
rm -rf *
33+
mv ../includeFaceSDK ./include
34+
35+
- name: Install Python
36+
uses: actions/setup-python@v5
37+
with:
38+
python-version: "${{ matrix.python-versions }}"
39+
40+
- name: Install build
41+
run: pip install build
42+
43+
- name: Build
44+
shell: cmd
45+
run: python -m build
46+
47+
- name: Upload artifacts
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: ${{ matrix.python-versions }}-windows
51+
path: dist\*.whl
52+
53+
54+
linux-build:
55+
runs-on: ubuntu-latest
56+
57+
steps:
58+
- uses: actions/checkout@v4
59+
60+
- name: Clone FaceSDK
61+
uses: actions/checkout@v4
62+
with:
63+
repository: 3DiVi/face-sdk
64+
path: FaceSDK
65+
66+
- name: Remove other files from FaceSDK
67+
shell: bash
68+
working-directory: FaceSDK
69+
run: |
70+
mv include ../includeFaceSDK
71+
rm -rf *
72+
mv ../includeFaceSDK ./include
73+
74+
- name: Install build
75+
run: pip install build
76+
77+
- name: Build
78+
run: python3 -m build
79+
80+
- name: Upload artifacts
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: linux
84+
path: dist/*.tar.gz

CMakeLists.txt

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
cmake_minimum_required(VERSION 3.27.0)
2+
3+
set(CMAKE_CXX_STANDARD 17)
4+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
5+
set(PYBIND11_TAG v2.13.6)
6+
7+
if (UNIX)
8+
set(PYTHON_EXECUTABLE /usr/bin/python3 CACHE STRING "Path to Python executable")
9+
else()
10+
find_package(Python3 REQUIRED)
11+
12+
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE} CACHE STRING "Path to Python executable")
13+
endif()
14+
set(FACE_SDK_INCLUDE_PATH "FaceSDK/include" CACHE STRING "Path to include directory")
15+
16+
if (NOT DEFINED ${PYTHON_MINOR_VERSION})
17+
execute_process(
18+
COMMAND ${PYTHON_EXECUTABLE} --version
19+
OUTPUT_VARIABLE PYTHON_FULL_VERSION
20+
)
21+
22+
message(STATUS "Full Python version: ${PYTHON_FULL_VERSION}")
23+
24+
string(REGEX REPLACE "Python [0-9]+\\.([0-9]+).*" "\\1" PYTHON_MINOR_VERSION "${PYTHON_FULL_VERSION}")
25+
endif()
26+
27+
message(STATUS "Python minor version: ${PYTHON_MINOR_VERSION}")
28+
29+
project(face_sdk_3divi)
30+
31+
include(FetchContent)
32+
33+
FetchContent_Declare(
34+
pybind11
35+
GIT_REPOSITORY https://github.com/pybind/pybind11
36+
GIT_TAG ${PYBIND11_TAG}
37+
OVERRIDE_FIND_PACKAGE
38+
)
39+
40+
FetchContent_MakeAvailable(pybind11)
41+
42+
find_package(pybind11 REQUIRED)
43+
44+
pybind11_add_module(
45+
${PROJECT_NAME}
46+
src/module.cpp
47+
src/FacerecService.cpp
48+
src/Context.cpp
49+
src/ProcessingBlock.cpp
50+
src/ContextTemplate.cpp
51+
src/DynamicTemplateIndex.cpp
52+
)
53+
54+
target_include_directories(
55+
${PROJECT_NAME} PRIVATE
56+
include
57+
${FACE_SDK_INCLUDE_PATH}
58+
)
59+
60+
if (DEFINED CUSTOM_INSTALL_PATH)
61+
install(TARGETS ${PROJECT_NAME} DESTINATION ${CUSTOM_INSTALL_PATH})
62+
else()
63+
if (UNIX)
64+
add_custom_target(
65+
generate_pyi ALL
66+
DEPENDS ${PROJECT_NAME}
67+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
68+
69+
COMMAND ${PYTHON_EXECUTABLE} -m venv .venv
70+
COMMAND .venv/bin/python -m pip install pybind11-stubgen
71+
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/*.so ${CMAKE_BINARY_DIR}/.venv/lib/python3.${PYTHON_MINOR_VERSION}/site-packages
72+
COMMAND ${CMAKE_BINARY_DIR}/.venv/bin/pybind11-stubgen -o ${CMAKE_BINARY_DIR} ${PROJECT_NAME}
73+
COMMAND ${CMAKE_COMMAND} -E rm -rf .venv
74+
)
75+
else()
76+
add_custom_target(
77+
generate_pyi ALL
78+
DEPENDS ${PROJECT_NAME}
79+
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
80+
81+
COMMAND ${PYTHON_EXECUTABLE} -m venv .venv
82+
COMMAND .venv/Scripts/python -m pip install pybind11-stubgen
83+
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${PROJECT_NAME}> ${CMAKE_BINARY_DIR}/.venv/Lib/site-packages
84+
COMMAND ${CMAKE_BINARY_DIR}/.venv/Scripts/pybind11-stubgen -o ${CMAKE_BINARY_DIR} ${PROJECT_NAME}
85+
COMMAND ${CMAKE_COMMAND} -E rm -rf .venv
86+
)
87+
endif()
88+
89+
install(TARGETS ${PROJECT_NAME} DESTINATION .)
90+
install(FILES ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pyi DESTINATION .)
91+
endif()

README.md

Whitespace-only changes.

include/Context.h

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#pragma once
2+
3+
#include <variant>
4+
#include <pybind11/stl.h>
5+
6+
#include <pybind11/pybind11.h>
7+
8+
#include <pbio/Context.h>
9+
10+
#include "ContextTemplate.h"
11+
12+
namespace py = pybind11;
13+
14+
namespace face_sdk_3divi
15+
{
16+
class DynamicTemplateIndex;
17+
18+
class Context
19+
{
20+
public:
21+
enum class Format
22+
{
23+
FORMAT_BGR = 0,
24+
FORMAT_RGB = 1,
25+
FORMAT_BGRA8888 = 2,
26+
FORMAT_YUV420 = 3,
27+
FORMAT_YUV_NV12 = 4,
28+
FORMAT_NV21 = 5,
29+
};
30+
31+
public:
32+
static py::bytes getBytesFromPtr(const Context& context, uint64_t size);
33+
34+
private:
35+
std::shared_ptr<pbio::Context> implementation;
36+
37+
private:
38+
static pbio::Context parsePythonBytes(const py::bytes& data);
39+
40+
static pbio::Context createContextFromFrame(uint8_t* data, int32_t width, int32_t height, Context::Format format, int32_t baseAngle);
41+
42+
static pbio::Context createContextFromJsonFile(const std::string& pathToJsonFile);
43+
44+
private:
45+
Context(pbio::Context::Ref* implementation);
46+
47+
public:
48+
Context();
49+
50+
Context(const py::dict& dict);
51+
52+
Context(const py::bytes& data);
53+
54+
Context(uint8_t* data, int32_t width, int32_t height, Context::Format format = Context::Format::FORMAT_BGR, int32_t baseAngle = 0);
55+
56+
Context(const std::string& pathToJsonFile);
57+
58+
Context(const Context& other);
59+
60+
Context& operator =(const Context& other);
61+
62+
void pushBack(const Context& value);
63+
64+
std::string serializeToJson() const;
65+
66+
bool contains(const std::string& key) const;
67+
68+
py::dict toDict() const;
69+
70+
uint64_t size() const;
71+
72+
void clear();
73+
74+
bool isNone() const;
75+
76+
bool isLong() const;
77+
78+
bool isBool() const;
79+
80+
bool isString() const;
81+
82+
bool isDouble() const;
83+
84+
bool isDataPtr() const;
85+
86+
bool isContextTemplate() const;
87+
88+
bool isDynamicTemplateIndex() const;
89+
90+
bool isArray() const;
91+
92+
bool isObject() const;
93+
94+
void setLong(int64_t value);
95+
96+
void setBool(bool value);
97+
98+
void setString(const std::string& value);
99+
100+
void setDouble(double value);
101+
102+
void setDataPtr(const py::bytes& value);
103+
104+
void setContextTemplate(const ContextTemplate& value);
105+
106+
void setDynamicTemplateIndex(const DynamicTemplateIndex& value);
107+
108+
void setValue(const py::handle& value);
109+
110+
int64_t getLong() const;
111+
112+
bool getBool() const;
113+
114+
std::string getString() const;
115+
116+
double getDouble() const;
117+
118+
py::bytes getBytes(uint64_t size) const;
119+
120+
ContextTemplate getContextTemplate() const;
121+
122+
DynamicTemplateIndex getDynamicTemplateIndex() const;
123+
124+
std::variant<py::handle, py::float_, ContextTemplate, DynamicTemplateIndex> getValue() const;
125+
126+
std::vector<std::string> getKeys();
127+
128+
Context operator[](int64_t index);
129+
130+
Context operator[](const std::string& key);
131+
132+
const Context operator[](int64_t index) const;
133+
134+
const Context operator[](const std::string& key) const;
135+
136+
void operator =(const py::str& value);
137+
138+
void operator =(const py::int_& value);
139+
140+
void operator =(const py::float_& value);
141+
142+
void operator =(const py::bool_& value);
143+
144+
void operator =(const py::bytes& value);
145+
146+
void operator =(const ContextTemplate& value);
147+
148+
void operator =(const DynamicTemplateIndex& value);
149+
150+
void operator =(const py::dict& dict);
151+
152+
void operator =(const py::list& list);
153+
154+
pbio::Context& operator *();
155+
156+
const pbio::Context& operator *() const;
157+
158+
~Context() = default;
159+
};
160+
}

include/ContextTemplate.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
#include <pbio/ContextTemplate.h>
4+
5+
#include <pybind11/pybind11.h>
6+
7+
namespace py = pybind11;
8+
9+
namespace face_sdk_3divi
10+
{
11+
class ContextTemplate
12+
{
13+
private:
14+
pbio::ContextTemplate::Ptr implementation;
15+
16+
public:
17+
ContextTemplate(pbio::ContextTemplate::Ptr implementation);
18+
19+
ContextTemplate(const py::bytes& data);
20+
21+
ContextTemplate(py::object& binaryReadStream);
22+
23+
int32_t size() const;
24+
25+
void save(py::object& binaryWriteStream) const;
26+
27+
std::string getMethodName() const;
28+
29+
pbio::ContextTemplate::Ptr& operator *();
30+
31+
const pbio::ContextTemplate::Ptr operator *() const;
32+
33+
~ContextTemplate() = default;
34+
};
35+
}

0 commit comments

Comments
 (0)