대부분 Rust인 Python 클라이언트를 구축한 방법
15454 단어 pythonrustshowdevopensource
이 게시물에서 우리는 Python 자체를 많이 작성하지 않고도 Python 클라이언트를 구축하기 위해 훌륭한 Rust 도구 중 일부를 활용할 수 있었던 방법에 대해 이야기할 것입니다.
개요
간단히 말해서, 우리는:
설정
시작하기 위해 두 가지 모두에 대해 설정된 새 프로젝트 폴더를 만듭니다.
Rust 및 Python,
cargo
및 venv
사용.cargo new --lib my-python-lib
cd my-python-lib
python -m venv venv
source venv/bin/activate
위는
my-python-lib
이라는 이름의 Rust 크레이트를 만든 다음 Python virtual environment 을 설정합니다.Note: You'll need to have the rust toolchain and python 3.6 or above installed.
녹 접착제
이것을
Cargo.toml
에 추가해야 합니다.[lib]
crate-type = ["cdylib"]
[dependencies]
cpython = { version = "0.5", features = ["extension-module"] }
[build-dependencies]
flapigen = "0.6.0-pre7"
crate-type = ["cdylib"]
은 Rust에게 일반적인 크레이트가 아닌 C 호환 dynamic library으로 크레이트를 빌드하도록 지시합니다. 이 크레이트 유형을 사용하면 Python 코드가 Rust가 아닌 컴파일된 C 코드인 것처럼 라이브러리와 상호 작용할 수 있습니다.이제 다음을 추가하여
build.rs
에 build script을 만듭니다.use flapigen::{LanguageConfig, PythonConfig};
use std::{env, path::Path};
fn main() {
let in_src = Path::new("src").join("glue.rs.in");
let out_dir = env::var("OUT_DIR").unwrap();
let out_src = Path::new(&out_dir).join("glue.rs");
let python_cfg = PythonConfig::new("my_python_lib".to_owned());
let flap_gen =
flapigen::Generator::new(LanguageConfig::PythonConfig(python_cfg)).rustfmt_bindings(true);
flap_gen.expand("python bindings", &in_src, &out_src);
println!("cargo:rerun-if-changed={}", in_src.display());
}
코드는 우리 프로젝트에서 실행되도록
flapigen
을 설정합니다. 빌드할 때 src/glue.rs.in
에 작성한 "접착제 코드"를 읽고 Python과 상호 작용하는 Rust 코드를 생성하여 ${OUT_DIR}/glue.rs
에 배치합니다.이제 다음과 같은
src/glue.rs.in
파일을 추가합니다.pub struct Foo {
val: i32
}
impl Foo {
pub fn new(val: i32) -> Self {
Self {
val
}
}
pub fn set_field(&mut self, new_val: i32) {
self.val = new_val;
}
pub fn val(&self) -> i32 {
self.val
}
}
foreign_class!(class Foo {
self_type Foo;
constructor Foo::new(_: i32) -> Foo;
fn Foo::set_field(&mut self, _: i32);
fn Foo::val(&self) -> i32;
});
이 간단한 예는 flapigen book에 게시되었으며 여기에 복사하여 붙여넣을 수 있습니다.
src/lib.rs
에는 현재 몇 가지 기본 테스트가 있어야 합니다. 다음과 같이 변경하겠습니다.#![allow(non_snake_case, unused)]
include!(concat!(env!("OUT_DIR"), "/glue.rs"));
이것은 빌드 스크립트를 사용할 때의 전형적인 Rust 패턴입니다. 코드는
${OUT_DIR}/glue.rs
에 있는 파일을 가져와서 빌드 디렉토리의 src/lib.rs
에 내용을 포함합니다. 결과는 생성된 코드를lib.rs
파일입니다.이 섹션에서는 Flapigen을 사용하여
foreign_class
매크로를 많은 cpython 기능으로 확장하고 extension module으로, 화물은 이를 cdylib
으로 컴파일합니다. 어떻게 생겼는지 보려면 cargo-expand
을 설치하고 cargo expand
을 실행하십시오. 생성된 많은 녹 코드를 얻을 수 있습니다.파이썬 접착제
setup
에서 가상 환경을 만들었으며 이제 다음을 통해 일부 Python 도구를 설치해야 합니다.$ source venv/bin/activate && pip install setuptools-rust
이제 python 패키지를 생성하기 위해 다음을 사용하여
setup.py
이라는 파일을 생성합니다.from setuptools import setup
from setuptools_rust import Binding, RustExtension
setup(
name="my-python-lib",
version="1.0",
rust_extensions=[RustExtension("my_python_lib", binding=Binding.RustCPython)],
# rust extensions are not zip safe, just like C-extensions.
zip_safe=False,
)
이것은 setuptools-rust을 바인딩으로 사용하는 것을 제외하고는 가장 기본적인
RustCPython
설정입니다.Rust와 Python 패키지를 빌드하려면
python setup.py develop
을 실행하면 됩니다. Python은 cargo
을 호출하고 cdylib
을 로컬 디렉토리로 이동합니다.모든 것을 테스트
다음이 포함된
simple.py
스크립트를 생성합니다.from my_python_lib import Foo
foo = Foo(1)
print(foo.val())
foo.set_field(11)
print(foo.val())
python simple.py
을 통해 스크립트를 실행하면 다음과 같은 결과가 나타납니다.$ python simple.py
1
11
자, Python에서 Rust를 호출했습니다!
결론
이 게시물의 출처는 fluvio-demo-apps-rust 저장소에서 얻을 수 있습니다.
이것들은 Python 래퍼를 설정하기 위한 기본 사항일 뿐입니다. Fluvio Python 클라이언트에서 Rust 상자는
_fluvio_python
입니다. Rust 구조체를 python 클래스로 감싸는 private python 모듈은 우리에게 멋진 documentation generation을 제공합니다.pypi
에 대한 패키징, 테스트 및 게시는 이 블로그의 범위를 벗어납니다. 추가 정보는 Makefile
및 github publishing workflow을 확인하십시오.이 블로그는 here에 처음 게시되었습니다.
Reference
이 문제에 관하여(대부분 Rust인 Python 클라이언트를 구축한 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/infinyon/how-we-built-our-python-client-that-s-mostly-rust-3p63텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)