Рубрики
Без рубрики

Веб-приложение, построенное с ржавчиной и Python

Когда я начал изучать ржавчину, я взял несколько моих проектов Python и переписал код с этим новым … Теги от ржавчины, Python.

Когда я начал изучать ржавчину, я сделал несколько моих проектов Python и переписал код с этим новым языком, я проверял Но тогда я узнал, что не было реальной альтернативы для некоторых библиотек, которые я использовал.

После поиска Craites.io Два ящика пристали мое внимание, Cpython и PYO3. , вы можете использовать как для написания нативных модулей Python, и запустить и взаимодействовать с Python.

Хотя вы можете найти некоторые примеры в их соответствующем репозитории GitHub, о том, как использовать Python в рамках проектов Rust Ruank, я не нашел так много информации о том, как вызвать функцию Python (во внешней библиотеке, на .py файл) от ржавчины, который возвращает значение или набор значений, которые будут обработаны.

Ответ на Puckoverflow’s Post Помоги мне готовить практический пример, который я представил в местном расширенном событии Google ввода/вывода, веб-приложение rust, которое подключается к Firebase через Python, извлеките данные и распечатывают его на HTML-документе.

К тому времени, когда я предложил разговорные веб-приложения с Rust & Firebase для Google I/O Продлен в прошлом году, я не знал, что нет ящика для подключения к Firebase, которая на самом деле работает. Поэтому я начал думать о возможности создать веб-приложение с ржавчиком и использовать только Python для подключения к Firebase.

Позвольте мне объяснить, как я построил проект.

Конфигурация

Прежде всего, я создал новый проект Rust Rust, используя Cargo:

cargo new rust-python-demo

Приведенная выше команда создаст новый каталог с именем Rust-Python-Demo Внутри этого каталога вы найдете SRC Dir, который содержит main.rs Файл, который позже будет изменен для записи кода приложения, и файл Cargo.toml Это проявление проекта.

Не забудьте перейти в новый каталог:

cd rust-python-demo

Cargo.toml.

Cargo.toml Должно быть изменено, чтобы выглядеть следующим образом:

[package]
name = "rust-python-demo"
version = "0.1.0"
authors = ["mattdark"]
edition = "2018"

[dependencies]
serde = "1.0.99"
serde_derive = "1.0.99"
serde_json = "1.0.40"
rocket = "0.4.2"

[dependencies.cpython]
version = "0.4"
features = ["python-3-7"]

[dependencies.rocket_contrib]
version = "0.4"
features = ["handlebars_templates"]

[[bin]]
name = "rust-python-demo"
path = "src/main.rs"

Раздел [Пакет] Содержит имя и версию приложения, информацию о разработчике и выпуске ржавчины, 2015 или 2018 года.

[Зависимости] Раздел имеет список зависимостей, необходимых для проекта, я использую Ракета , веб-каркас для ржавчины, а также Потрясающий , рамки для сериализации и десериализации структур данных ржавчины. Для CPYHON вы можете указать версию Python, которую вы будете использовать, и поскольку Rocket поддерживает поддержку обеих рулей, так и для TERA (шаблонные двигатели), вы должны указать тот, который используется для проекта, в этом случае руль.

Чтобы назначить определенное имя бинарного приложения, вы можете сделать это в [[BIN]] Раздел, указывающий имя файла исходного кода.

pyproject.toml.

pyproject.toml Является ли файл, который поэзия использует для управления проектом Python и его зависимостями. Он содержит информацию о проекте, как имя, версия, описание и авторы, в [Tool.poetry] раздел. Версия Python и список зависимостей должна быть указана в [Tool.poetry.dependonds] Раздел, для этого проекта, я использую любую версию Python, больше или равную 3.7.3 и меньше чем 3.8 Отказ Для подключения к Firebase я использую Firebase Библиотека и остальные пакеты являются зависимостями этого.

Файл должен выглядеть следующим образом:

[tool.poetry]
name = "rust-python-demo"
version = "0.1.0"
description = ""
authors = ["Mario Garcia "]

[tool.poetry.dependencies]
python = "^3.7.3"
firebase = "*"
python-jwt = "*"
gcloud = "*"
sseclient = "*"
pycrypto = "*"
requests-toolbelt = "*"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

Питон

Зачем использовать определенную версию Python, отличную от одной доступной в вашей системе или той, которую вы установили из репозиториев? Некоторые дистрибутивы Linux, особенно тех, кто прокатный релиз, предложит новейшую стабильную версию доступных Python, 3.8.2 в момент написания этой статьи.

Другие дистрибутивы будут иметь последний выпуск Python 3.6 или Python 3.7, но вам, вероятно, понадобится другая версия в зависимости от совместимости и поддержки библиотек, которые вы используете для проекта.

Так что это момент, когда Pyenv может помочь, как это позволяет иметь другие версии Python, установленные в вашей системе дружественным способом.

Чтобы перечислить версию Python, доступных через PENV, запустите следующую команду:

pyenv install --list

Для этого проекта я использую Python 3.7.7. Перед установкой версии Python вы будете использовать для проекта, имейте в виду, что если вы хотите встроить Python в Rust, общие библиотеки должны быть построены для Python. Запустите следующую команду, чтобы правильно установить Python:

env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.7.7

После запуска вышеуказанной команды добавьте каталог общих библиотек к переменной среды LD_LIBRARY_PATH следующим образом:

export LD_LIBRARY_PATH=~/.pyenv/versions/3.7.7/lib/

Поэзия

Перед установкой зависимости проекта необходимо указать версию Python, которая будет использоваться для поэзии для создания виртуальной среды проекта, выполните следующую команду:

poetry env use 3.7.7

Затем установите зависимости проекта путем работы:

poetry install

Эта команда также создаст виртуальную среду.

Примечание. Если вам не требуется виртуальная среда для вашего проекта, вы можете запустить следующую команду перед Поэзия устанавливает :

poetry config virtualenvs.create false

Ржавчина

CPYHON и PYO3 работает с ночной версией ржавчины, поэтому перед записью кода вашего приложения измените набора инструментов проекта, запустив:

rustup override set nightly

Понимание кода

Структура каталогов

После настройки приложения у вас будет Cargo.toml , pyproject.toml и main.rs Файл в SRC Каталог, который он будет изменен позже, чтобы поставить код приложения.

В SRC каталог A Python DIR должен быть создан, чтобы поставить модуль Python, который сделает подключение к Firebase и извлечь из него данные, названные Pyrebase.py Отказ

В корневом каталоге Шаблоны и статический должен быть добавлен дирижер. Шаблоны руль и статические файлы (например, CSS, JavaScript, Pictures) будут храниться в этих режимах.

Firebase

Перейти к console.firebase.google.com и добавить новый проект, я назову это Rust Python Demo Отказ

Затем добавьте Firebase в веб-приложение, вы получите следующие данные конфигурации, которые вам нужно будет настроить модуль Python:

var firebaseConfig = {
    apiKey: "APIKEY",
    authDomain: "rust-python-demo.firebaseapp.com",
    databaseURL: "https://rust-python-demo.firebaseio.com",
    projectId: "rust-python-demo",
    storageBucket: "rust-python-demo.appspot.com",
    messagingSenderId: "SENDERID",
    appId: "APPID"
  };

И, наконец, пойти в База данных с левой боковой панели и Создать базу данных Отказ Для этого демо я буду хранить список случайных имен, созданных через listofrandomnames.com Отказ

Структура базы данных будет выглядеть следующим образом, вы можете импортировать следующие JSON в базу данных для тестирования:

Firebase.json.

{
  "speakers" : {
    "speaker1" : {
      "id" : "1",
      "last_name" : "Moore",
      "name" : "Madie"
    },
    "speaker2" : {
      "id" : "2",
      "last_name" : "Nathanson",
      "name" : "Norbert"
    },
    "speaker3" : {
      "id" : "3",
      "last_name" : "Mcconelle",
      "name" : "Major"
    },
    "speaker4" : {
      "id" : "4",
      "last_name" : "Schalk",
      "name" : "Sophia"
    },
    "speaker5" : {
      "id" : "5",
      "last_name" : "Bertrand",
      "name" : "Benny"
    }
  }
}

Имя базы данных – Динамики Поскольку эта демонстрация является частью веб-приложения, над которым я работаю.

Не забудьте настроить правила вашей базы данных следующим образом:

{
  "rules": {
    ".read": true,
    ".write": false
  }
}

Питон

SRC/Python/Pyrebase.py

import json
from firebase import Firebase
def read_data(self):
    config = {
        "apiKey": "APIKEY",
        "authDomain": "rust-python-demo.firebaseapp.com",
        "databaseURL": "https://rust-python-demo.firebaseio.com",
        "projectId": "rust-python-demo",
        "storageBucket": "rust-python-demo.appspot.com",
        "messagingSenderId": "MESSAGINGSENDERID"
    }
    firebase = Firebase(config)

    speaker = list()
    db = firebase.database()
    all_speakers = db.child("speakers").get()
    for x in all_speakers.each():
        speaker.append(x.val())
    s = json.dumps(speaker)
    return s

Для этого модуля я использую JSON и Firebase Библиотеки. У него есть только функция, названная read_data () Это подключится к Firebase и извлеките данные из базы данных.

Внутри функции, которую я определил config Переменная, которая имеет данные конфигурации, необходимые для подключения к Firebase.

После подключения к Firebase я получаю все реестры, хранящиеся в базе данных, и добавьте ее к Спикер Список и преобразовать этот список на структуру JSON для Rust, чтобы правильно импортировать эти данные.

Ржавчина

SRC/Main.rs.

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

extern crate rocket_contrib;
extern crate cpython;

use cpython::{Python, PyResult, PyModule};

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use std::collections::HashMap;
use std::path::{Path, PathBuf};
use crate::handlebars::{to_json};

use rocket::response::NamedFile;
use rocket_contrib::templates::{Template, handlebars};

#[derive(Serialize, Deserialize, Debug)]
pub struct Speakers {
    pub id: String,
    pub name: String,
    pub last_name: String,
}

const FIRE_PY: &'static str = include_str!("./python/pyrebase.py");

#[get("/")]
fn index() -> Template {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let s = run_python(py).unwrap();
    let mut data = HashMap::new();
    data.insert("speakers".to_string(), to_json(&s));
    Template::render("index", &data)
}

fn run_python(py: Python<'_>) -> PyResult> {
    let m = module_from_str(py, "pyrebase", FIRE_PY)?;
    let out: String = m.call(py, "read_data", (2,), None)?.extract(py)?;
    let speakers: Vec = serde_json::from_str(&out).unwrap();
    Ok(speakers)
}

fn module_from_str(py: Python<'_>, name: &str, source: &str) -> PyResult {
    let m = PyModule::new(py, name)?;
    m.add(py, "__builtins__", py.import("builtins")?)?;

    let m_locals = m.get(py, "__dict__")?.extract(py)?;
    py.run(source, Some(&m_locals), None)?;
    Ok(m)
}

#[get("/", rank=3)]
fn files(file: PathBuf) -> Option {
    NamedFile::open(Path::new("static/").join(file)).ok()
}

fn rocket() -> rocket::Rocket {
    rocket::ignite().mount("/", routes![index, files])
    .attach(Template::fairing())
}

fn main() {
    rocket().launch();
}

Сначала в Главная () Функция Ракетное приложение проходит через Ракета () Функция, где устанавливаются маршруты приложения, и шаблон обтекал к приложению.

Как только загружает документ HTML, он имеет два маршрута, Индекс и Файлы первый указывает на Индекс () Функция, где загружен корня приложения, и последний, указывающий на Файлы () Функция, где статические файлы в статический каталог загружен.

В Индекс () Функция, интерпретатор Python встроен, а ссылка на двоич на Python присваивается для PY Переменная, в первых двух линиях.

Тогда функция Run_Python () называется. В первой строке module_from_str () Функция называется, где Pyrebase Модуль загружен.

После этого read_data () Способ Python называется, и значение, возвращаемое им, назначает OUT Переменная. Тогда OUT Переменная десериализация, и значения преобразуются в вектор, используя структуру Динамики Отказ

Вектор Динамики возвращается в Индекс () Функция, где она называлась и преобразована в хешмап, чтобы пройти значения в Индекс шаблон.

Шаблон

Шаблоны/index.html.hbs.


    
{{ #each speakers }} {{ /each }}
ID Name Last Name
{{ id }} {{ name }} {{ last_name }}
...

Индекс HTML-документ будет отображать только данные, полученные из базы данных в таблице.

Запуск приложения

Код приложения написан, поэтому пришло время запускать демонстрацию.

Проект должен быть построен первым, выполните следующую команду с терминала:

poetry run cargo build --release

Как приложение проходит через виртуальную завивку, созданную поэзией, Поэзия бежит Команда должна быть выполнена в первую очередь, а затем проект построен для производства с Грузовая сборка --release Отказ

Груз создал бинарное имя Rust-Python-Demo в Цель/освобождение каталог. Чтобы запустить приложение, напишите следующую команду в терминале:

poetry run ./target/release/rust-python-demo

Теперь иди к localhost: 8000 в вашем браузере. Вы увидите следующий экран.

Демонстрация веб-приложения, построенного с ржавчиной и Python, поднимается и работает, чтобы получить код перейти к gitlab.com/mattdark/rust-python-demo Отказ

Оригинал: “https://dev.to/mattdark/a-web-app-built-with-rust-and-python-1fkc”