├── .gitignore ├── LICENSE ├── README.md ├── chapter_eight ├── build_our_model │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.toml │ ├── MANIFEST.in │ ├── flitton_oasis_risk_modelling │ │ ├── __init__.py │ │ ├── footprint.csv │ │ └── vulnerability.csv │ ├── setup.py │ └── src │ │ ├── footprint │ │ ├── mod.rs │ │ ├── processes.rs │ │ └── structs.rs │ │ ├── lib.rs │ │ └── vulnerabilities │ │ ├── mod.rs │ │ ├── processes.rs │ │ └── structs.rs ├── footprint.csv ├── testing_our_model │ └── testing_model.py └── vulnerability.csv ├── chapter_eleven ├── give_the_interface_a_native_feel_with_objects │ ├── calculate_coordinates.py │ ├── run.py │ └── test_flyweight.py ├── keep_it_simple_with_piping │ ├── fib.rs │ ├── input.py │ ├── output.py │ └── pure_python.py ├── keeping-it-simple-with-rayon │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── using_traits_as_opposed_to_objects │ ├── Cargo.toml │ └── src │ ├── actions.rs │ ├── main.rs │ ├── objects.rs │ ├── people.rs │ └── traits.rs ├── chapter_five ├── basic_layout │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ └── __init__.py │ ├── setup.py │ └── src │ │ └── lib.rs ├── comparison_script.py ├── fib_calcs │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ └── singleton.py │ ├── setup.py │ └── src │ │ ├── fib_calcs │ │ ├── fib_number.rs │ │ ├── fib_numbers.rs │ │ └── mod.rs │ │ └── lib.rs └── testing │ ├── .cargo │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ ├── __init__.py │ ├── counter.py │ ├── fib_number_adapter.py │ ├── fib_number_command.py │ └── singleton.py │ ├── setup.py │ └── src │ ├── fib_calcs │ ├── fib_number.rs │ ├── fib_numbers.rs │ └── mod.rs │ └── lib.rs ├── chapter_four ├── fib_calc_package │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── flitton_fib_py │ │ ├── __init__.py │ │ ├── cmd │ │ │ ├── __init__.py │ │ │ └── fib_numb.py │ │ └── fib_calcs │ │ │ ├── __init__.py │ │ │ ├── fib_number.py │ │ │ └── fib_numbers.py │ ├── scripts │ │ └── run_tests.sh │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ └── flitton_fib_py │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── test_fib_number.py │ │ └── test_fib_numbers.py ├── fully_automated_deployment │ ├── .github │ │ └── workflows │ │ │ ├── publish-package.yml │ │ │ └── run-tests.yml │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── flitton_fib_py │ │ ├── __init__.py │ │ ├── cmd │ │ │ ├── __init__.py │ │ │ └── fib_numb.py │ │ └── fib_calcs │ │ │ ├── __init__.py │ │ │ ├── fib_number.py │ │ │ └── fib_numbers.py │ ├── get_latest_version.py │ ├── requirements.txt │ ├── scripts │ │ └── run_tests.sh │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ └── flitton_fib_py │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── test_fib_number.py │ │ └── test_fib_numbers.py ├── managing_dependencies │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── flitton_fib_py │ │ ├── __init__.py │ │ ├── cmd │ │ │ ├── __init__.py │ │ │ └── fib_numb.py │ │ └── fib_calcs │ │ │ ├── __init__.py │ │ │ ├── fib_number.py │ │ │ └── fib_numbers.py │ ├── requirements.txt │ ├── scripts │ │ └── run_tests.sh │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ └── flitton_fib_py │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── test_fib_number.py │ │ └── test_fib_numbers.py ├── module_tests │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── flitton_fib_py │ │ ├── __init__.py │ │ ├── cmd │ │ │ ├── __init__.py │ │ │ └── fib_numb.py │ │ └── fib_calcs │ │ │ ├── __init__.py │ │ │ ├── fib_number.py │ │ │ └── fib_numbers.py │ ├── scripts │ │ └── run_tests.sh │ ├── setup.py │ └── tests │ │ ├── __init__.py │ │ └── flitton_fib_py │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── test_fib_number.py │ │ └── test_fib_numbers.py ├── packaged_module │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── flitton_fib_py │ │ └── __init__.py │ └── setup.py └── pip_setup │ ├── README.md │ ├── packt_fibonacci │ └── __init__.py │ └── setup.py ├── chapter_nine ├── building_a_message_bus │ ├── deployment │ │ ├── docker-compose.yml │ │ └── nginx │ │ │ └── nginx.conf │ ├── docker-compose.yml │ └── src │ │ ├── Dockerfile │ │ ├── __init__.py │ │ ├── alembic.ini │ │ ├── alembic │ │ ├── README │ │ ├── env.py │ │ └── script.py.mako │ │ ├── app.py │ │ ├── config.py │ │ ├── config.yml │ │ ├── data_access.py │ │ ├── fib_calcs │ │ ├── __init__.py │ │ └── fib_calculation.py │ │ ├── live_config.yml │ │ ├── models │ │ ├── __init__.py │ │ └── database │ │ │ ├── __init__.py │ │ │ └── fib_entry.py │ │ ├── requirements.txt │ │ └── task_queue │ │ ├── __init__.py │ │ ├── engine.py │ │ └── fib_calc_task.py ├── building_flask_app │ ├── deployment │ │ ├── docker-compose.yml │ │ └── nginx │ │ │ └── nginx.conf │ └── src │ │ ├── Dockerfile │ │ ├── __init__.py │ │ ├── app.py │ │ ├── fib_calcs │ │ ├── __init__.py │ │ └── fib_calculation.py │ │ └── requirements.txt └── defining_our_data_access_layer │ ├── deployment │ ├── docker-compose.yml │ └── nginx │ │ └── nginx.conf │ ├── docker-compose.yml │ └── src │ ├── Dockerfile │ ├── __init__.py │ ├── alembic.ini │ ├── alembic │ ├── README │ ├── env.py │ └── script.py.mako │ ├── app.py │ ├── config.py │ ├── config.yml │ ├── data_access.py │ ├── fib_calcs │ ├── __init__.py │ └── fib_calculation.py │ ├── live_config.yml │ ├── models │ ├── __init__.py │ └── database │ │ ├── __init__.py │ │ └── fib_entry.py │ └── requirements.txt ├── chapter_one ├── borrowing.rs ├── error_handling.rs ├── flask_app.py ├── hello_world.rs ├── print_function.rs └── string_literals.rs ├── chapter_seven ├── adding_vectors_in_rust │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── config_number_command.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ ├── object_interface.py │ │ └── singleton.py │ ├── setup.py │ ├── src │ │ ├── fib_calcs │ │ │ ├── fib_number.rs │ │ │ ├── fib_numbers.rs │ │ │ └── mod.rs │ │ ├── interface │ │ │ ├── config.rs │ │ │ ├── mod.rs │ │ │ └── object.rs │ │ └── lib.rs │ └── using_function_from_package.py ├── building_a_model_in_numpy │ ├── __init__.py │ └── basic_model.py ├── building_a_python_model │ └── numpy_model.py ├── exploring_numpy │ ├── __init__.py │ └── creating_numpy.py ├── numpy_model_in_rust │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── config_number_command.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ ├── numpy_model.py │ │ ├── object_interface.py │ │ └── singleton.py │ ├── setup.py │ ├── src │ │ ├── fib_calcs │ │ │ ├── fib_number.rs │ │ │ ├── fib_numbers.rs │ │ │ └── mod.rs │ │ ├── interface │ │ │ ├── config.rs │ │ │ ├── mod.rs │ │ │ └── object.rs │ │ ├── lib.rs │ │ └── numpy_model.rs │ └── testing_numpy_rust_in_python.py └── using_numpy_in_rust │ ├── .cargo │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ ├── __init__.py │ ├── config_number_command.py │ ├── counter.py │ ├── fib_number_adapter.py │ ├── fib_number_command.py │ ├── object_interface.py │ └── singleton.py │ ├── setup.py │ ├── src │ ├── fib_calcs │ │ ├── fib_number.rs │ │ ├── fib_numbers.rs │ │ └── mod.rs │ ├── interface │ │ ├── config.rs │ │ ├── mod.rs │ │ └── object.rs │ └── lib.rs │ └── testing_numpy_rust_in_python.py ├── chapter_six ├── complex_data_structures │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── config_number_command.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ └── singleton.py │ ├── setup.py │ └── src │ │ ├── fib_calcs │ │ ├── fib_number.rs │ │ ├── fib_numbers.rs │ │ └── mod.rs │ │ ├── interface │ │ ├── config.rs │ │ └── mod.rs │ │ └── lib.rs ├── constructing_our_own_python_objects │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── config_number_command.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ └── singleton.py │ ├── setup.py │ └── src │ │ ├── class_module │ │ ├── fib_processor.rs │ │ └── mod.rs │ │ ├── fib_calcs │ │ ├── fib_number.rs │ │ ├── fib_numbers.rs │ │ └── mod.rs │ │ ├── interface │ │ ├── config.rs │ │ └── mod.rs │ │ └── lib.rs ├── inspecting_python_objects │ ├── .cargo │ │ └── config │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── flitton_fib_rs │ │ ├── __init__.py │ │ ├── config_number_command.py │ │ ├── counter.py │ │ ├── fib_number_adapter.py │ │ ├── fib_number_command.py │ │ ├── object_interface.py │ │ └── singleton.py │ ├── setup.py │ └── src │ │ ├── fib_calcs │ │ ├── fib_number.rs │ │ ├── fib_numbers.rs │ │ └── mod.rs │ │ ├── interface │ │ ├── config.rs │ │ ├── mod.rs │ │ └── object.rs │ │ └── lib.rs └── timing_script.py ├── chapter_ten ├── deploying_nightly_rust_in_rust │ ├── diesel_pip_package │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── diesel.toml │ │ ├── rust_db_cloning │ │ │ └── __init__.py │ │ ├── setup.py │ │ └── src │ │ │ ├── database.rs │ │ │ ├── lib.rs │ │ │ ├── models.rs │ │ │ └── schema.rs │ ├── flask_app │ │ ├── deployment │ │ │ ├── docker-compose.yml │ │ │ └── nginx │ │ │ │ └── nginx.conf │ │ ├── docker-compose.yml │ │ └── src │ │ │ ├── Dockerfile │ │ │ ├── __init__.py │ │ │ ├── alembic.ini │ │ │ ├── alembic │ │ │ ├── README │ │ │ ├── env.py │ │ │ └── script.py.mako │ │ │ ├── app.py │ │ │ ├── build_image.sh │ │ │ ├── config.py │ │ │ ├── config.yml │ │ │ ├── data_access.py │ │ │ ├── fib_calcs │ │ │ ├── __init__.py │ │ │ └── fib_calculation.py │ │ │ ├── live_config.yml │ │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── database │ │ │ │ ├── __init__.py │ │ │ │ └── fib_entry.py │ │ │ ├── requirements.txt │ │ │ └── task_queue │ │ │ ├── __init__.py │ │ │ ├── engine.py │ │ │ └── fib_calc_task.py │ └── pip_package │ │ └── src │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── enums.py │ │ └── fib_calculation.py ├── deploying_with_a_private_github_repository │ ├── flask_app │ │ ├── deployment │ │ │ ├── docker-compose.yml │ │ │ └── nginx │ │ │ │ └── nginx.conf │ │ ├── docker-compose.yml │ │ └── src │ │ │ ├── Dockerfile │ │ │ ├── __init__.py │ │ │ ├── alembic.ini │ │ │ ├── alembic │ │ │ ├── README │ │ │ ├── env.py │ │ │ └── script.py.mako │ │ │ ├── app.py │ │ │ ├── build_image.sh │ │ │ ├── config.py │ │ │ ├── config.yml │ │ │ ├── data_access.py │ │ │ ├── fib_calcs │ │ │ ├── __init__.py │ │ │ └── fib_calculation.py │ │ │ ├── live_config.yml │ │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── database │ │ │ │ ├── __init__.py │ │ │ │ └── fib_entry.py │ │ │ ├── requirements.txt │ │ │ └── task_queue │ │ │ ├── __init__.py │ │ │ ├── engine.py │ │ │ └── fib_calc_task.py │ └── pip_package │ │ └── src │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── enums.py │ │ └── fib_calculation.py ├── fusing_rust_into_flask_and_celery │ ├── flask_app │ │ ├── deployment │ │ │ ├── docker-compose.yml │ │ │ └── nginx │ │ │ │ └── nginx.conf │ │ ├── docker-compose.yml │ │ └── src │ │ │ ├── Dockerfile │ │ │ ├── __init__.py │ │ │ ├── alembic.ini │ │ │ ├── alembic │ │ │ ├── README │ │ │ ├── env.py │ │ │ └── script.py.mako │ │ │ ├── app.py │ │ │ ├── config.py │ │ │ ├── config.yml │ │ │ ├── data_access.py │ │ │ ├── fib_calcs │ │ │ ├── __init__.py │ │ │ └── fib_calculation.py │ │ │ ├── live_config.yml │ │ │ ├── models │ │ │ ├── __init__.py │ │ │ └── database │ │ │ │ ├── __init__.py │ │ │ │ └── fib_entry.py │ │ │ ├── requirements.txt │ │ │ └── task_queue │ │ │ ├── __init__.py │ │ │ ├── engine.py │ │ │ └── fib_calc_task.py │ └── pip_package │ │ └── src │ │ ├── __init__.py │ │ └── fib_calcs │ │ ├── __init__.py │ │ ├── enums.py │ │ └── fib_calculation.py └── fusing_rust_with_data_access │ ├── diesel_pip_package │ ├── Cargo.lock │ ├── Cargo.toml │ ├── diesel.toml │ ├── rust_db_cloning │ │ └── __init__.py │ ├── setup.py │ └── src │ │ ├── database.rs │ │ ├── lib.rs │ │ ├── models.rs │ │ └── schema.rs │ ├── flask_app │ ├── deployment │ │ ├── docker-compose.yml │ │ └── nginx │ │ │ └── nginx.conf │ ├── docker-compose.yml │ └── src │ │ ├── Dockerfile │ │ ├── __init__.py │ │ ├── alembic.ini │ │ ├── alembic │ │ ├── README │ │ ├── env.py │ │ └── script.py.mako │ │ ├── app.py │ │ ├── build_image.sh │ │ ├── config.py │ │ ├── config.yml │ │ ├── data_access.py │ │ ├── fib_calcs │ │ ├── __init__.py │ │ └── fib_calculation.py │ │ ├── live_config.yml │ │ ├── models │ │ ├── __init__.py │ │ └── database │ │ │ ├── __init__.py │ │ │ └── fib_entry.py │ │ ├── requirements.txt │ │ └── task_queue │ │ ├── __init__.py │ │ ├── engine.py │ │ └── fib_calc_task.py │ └── pip_package │ └── src │ ├── __init__.py │ └── fib_calcs │ ├── __init__.py │ ├── enums.py │ └── fib_calculation.py ├── chapter_three ├── processes │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── python_processes.py ├── python_threads.py ├── rust_processes │ ├── fib_process.rs │ └── multiprocessing.rs ├── rust_threading │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs └── threads_and_closures │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ └── main.rs └── chapter_two ├── basic_setup ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── defining_interfaces ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── main.rs │ └── stocks │ ├── enums │ ├── mod.rs │ └── order_types.rs │ ├── mod.rs │ └── structs │ ├── mod.rs │ ├── order.rs │ └── stock.rs ├── interacting_with_environment ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── main.rs │ └── stocks │ ├── enums │ ├── mod.rs │ └── order_types.rs │ ├── mod.rs │ └── structs │ ├── mod.rs │ ├── order.rs │ └── stock.rs └── structuring_code ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src ├── main.rs └── stocks ├── mod.rs └── structs ├── mod.rs ├── stock.rs └── utils.rs /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | 7 | [target.aarch64-apple-darwin] 8 | rustflags = [ 9 | "-C", "link-arg=-undefined", 10 | "-C", "link-arg=dynamic_lookup", 11 | ] 12 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_oasis_risk_modelling" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | csv = "1.1" 9 | serde = { version = "1", features = ["derive"] } 10 | 11 | 12 | [lib] 13 | name = "flitton_oasis_risk_modelling" 14 | crate-type=["rlib", "cdylib"] 15 | 16 | [dependencies.pyo3] 17 | version = "0.13.2" 18 | features = ["extension-module"] 19 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include flitton_oasis_risk_modelling/*.csv 2 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/flitton_oasis_risk_modelling/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_oasis_risk_modelling import * 2 | import os 3 | 4 | 5 | def construct_model(event_ids): 6 | dir_path = os.path.dirname(os.path.realpath(__file__)) 7 | return get_model(event_ids, str(dir_path)) 8 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/flitton_oasis_risk_modelling/footprint.csv: -------------------------------------------------------------------------------- 1 | event_id,areaperil_id,intensity_bin_id,probability 2 | 1,10,1,0.47 3 | 1,10,2,0.53 4 | 2,20,1,0.3 5 | 2,20,2,0.7 6 | 3,30,3,0.28 7 | 3,30,4,0.72 8 | 4,40,4,0.81 9 | 4,40,5,0.19 -------------------------------------------------------------------------------- /chapter_eight/build_our_model/flitton_oasis_risk_modelling/vulnerability.csv: -------------------------------------------------------------------------------- 1 | vulnerability_id,intensity_bin_id,damage_bin_id,probability 2 | 1,1,1,0.45 3 | 1,2,2,0.65 4 | 2,3,1,0.78 5 | 2,4,2,0.22 6 | 3,1,1,0.89 7 | 3,4,3,0.11 8 | 4,2,1,0.35 9 | 4,5,3,0.65 -------------------------------------------------------------------------------- /chapter_eight/build_our_model/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="flitton-oasis-risk-modelling", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".flitton_oasis_risk_modelling.flitton_oasis_risk_modelling", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["flitton_oasis_risk_modelling"], 15 | include_package_data=True, 16 | package_data={'': ['*.csv']}, 17 | zip_safe=False, 18 | ) 19 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/src/footprint/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod structs; 2 | pub mod processes; 3 | 4 | use structs::FootPrint; 5 | use processes::{merge_footprint_with_events, read_footprint}; 6 | 7 | 8 | pub fn merge_event_ids_with_footprint(event_ids: Vec, 9 | base_path: String) -> Vec { 10 | let foot_prints = read_footprint(base_path).unwrap(); 11 | return merge_footprint_with_events(event_ids, foot_prints) 12 | } 13 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/src/footprint/processes.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::fs::File; 3 | use csv; 4 | 5 | use super::structs::FootPrint; 6 | 7 | 8 | pub fn read_footprint(mut base_path: String) -> 9 | Result, Box> { 10 | base_path.push_str("/footprint.csv"); 11 | let file = File::open(base_path.as_str())?; 12 | let mut rdr = csv::Reader::from_reader(file); 13 | 14 | let mut buffer = Vec::new(); 15 | 16 | for result in rdr.deserialize() { 17 | // Notice that we need to provide a type hint for automatic 18 | // deserialization. 19 | let record: FootPrint = result?; 20 | buffer.push(record); 21 | } 22 | Ok(buffer) 23 | } 24 | 25 | pub fn merge_footprint_with_events(event_ids: Vec, 26 | footprints: Vec) -> Vec { 27 | let mut buffer = Vec::new(); 28 | 29 | for event_id in event_ids { 30 | for footprint in &footprints { 31 | if footprint.event_id == event_id { 32 | buffer.push(footprint.clone()); 33 | } 34 | } 35 | } 36 | return buffer 37 | } 38 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/src/footprint/structs.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | 4 | #[derive(Debug, Deserialize, Clone)] 5 | pub struct FootPrint { 6 | pub event_id: i32, 7 | pub areaperil_id: i32, 8 | pub intensity_bin_id: i32, 9 | pub probability: f32 10 | } 11 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/src/vulnerabilities/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod structs; 2 | pub mod processes; 3 | 4 | 5 | use structs::VulnerabilityFootPrint; 6 | use processes::{merge_footprint_with_vulnerabilities, read_vulnerabilities}; 7 | use crate::footprint::structs::FootPrint; 8 | 9 | 10 | pub fn merge_vulnerabilities_with_footprint(footprint: Vec, mut base_path: String) -> Vec { 11 | let vulnerabilities = read_vulnerabilities(base_path).unwrap(); 12 | return merge_footprint_with_vulnerabilities(vulnerabilities, footprint) 13 | } 14 | -------------------------------------------------------------------------------- /chapter_eight/build_our_model/src/vulnerabilities/structs.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | 3 | 4 | #[derive(Debug, Deserialize, Clone)] 5 | pub struct Vulnerability { 6 | pub vulnerability_id: i32, 7 | pub intensity_bin_id: i32, 8 | pub damage_bin_id: i32, 9 | pub probability: f32 10 | } 11 | 12 | 13 | #[derive(Debug, Deserialize, Clone)] 14 | pub struct VulnerabilityFootPrint { 15 | pub vulnerability_id: i32, 16 | pub intensity_bin_id: i32, 17 | pub damage_bin_id: i32, 18 | pub damage_probability: f32, 19 | pub event_id: i32, 20 | pub areaperil_id: i32, 21 | pub footprint_probability: f32, 22 | pub total_probability: f32 23 | } 24 | -------------------------------------------------------------------------------- /chapter_eight/footprint.csv: -------------------------------------------------------------------------------- 1 | event_id,areaperil_id,intensity_bin_id,probability 2 | 1,10,1,0.47 3 | 1,10,2,0.53 4 | 2,20,1,0.3 5 | 2,20,2,0.7 6 | 3,30,3,0.28 7 | 3,30,4,0.72 8 | 4,40,4,0.81 9 | 4,40,5,0.19 -------------------------------------------------------------------------------- /chapter_eight/vulnerability.csv: -------------------------------------------------------------------------------- 1 | vulnerability_id,intensity_bin_id,damage_bin_id,probability 2 | 1,1,1,0.45 3 | 1,2,2,0.65 4 | 2,3,1,0.78 5 | 2,4,2,0.22 6 | 3,1,1,0.89 7 | 3,4,3,0.11 8 | 4,2,1,0.35 9 | 4,5,3,0.65 -------------------------------------------------------------------------------- /chapter_eleven/give_the_interface_a_native_feel_with_objects/calculate_coordinates.py: -------------------------------------------------------------------------------- 1 | from rust_package import calculate_coordinates 2 | 3 | 4 | class FlyWeight(type): 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | key = str(args[0]) + str(args[1]) 9 | if key not in cls._instances: 10 | cls._instances[key] = super( 11 | FlyWeight, cls).__call__(*args, **kwargs) 12 | return cls._instances[key] 13 | 14 | 15 | class Particle(metaclass=FlyWeight): 16 | def __init__(self, v_x, v_y): 17 | self.co_dict = calculate_coordinates(v_x, v_y) 18 | 19 | def get_position(self, time) -> tuple: 20 | return self.co_dict[time] 21 | 22 | @property 23 | def times(self): 24 | return list(self.co_dict.keys()) 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /chapter_eleven/give_the_interface_a_native_feel_with_objects/run.py: -------------------------------------------------------------------------------- 1 | from .calculate_coordinates import Particle 2 | 3 | 4 | particle = Particle(20, 30) 5 | 6 | x_positions = [] 7 | y_positions = [] 8 | 9 | for t in particle.times: 10 | x, y = particle.get_position(t) 11 | x_positions.append(x) 12 | y_positions.append(y) 13 | -------------------------------------------------------------------------------- /chapter_eleven/give_the_interface_a_native_feel_with_objects/test_flyweight.py: -------------------------------------------------------------------------------- 1 | from .calculate_coordinates import Particle 2 | 3 | 4 | test = Particle(4, 6) 5 | test_two = Particle(3, 8) 6 | test_three = Particle(4, 6) 7 | 8 | print(id(test)) 9 | print(id(test_three)) 10 | print(id(test_two)) 11 | -------------------------------------------------------------------------------- /chapter_eleven/keep_it_simple_with_piping/fib.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::io::prelude::*; 3 | 4 | 5 | pub fn fibonacci_reccursive(n: i32) -> u64 { 6 | match n { 7 | 1 | 2 => 1, 8 | _ => fibonacci_reccursive(n - 1) + 9 | fibonacci_reccursive(n - 2) 10 | } 11 | } 12 | 13 | 14 | fn main() { 15 | let stdin = io::stdin(); 16 | let stdout = std::io::stdout(); 17 | let mut writer = stdout.lock(); 18 | 19 | for line in stdin.lock().lines() { 20 | let input_int: i32 = line.unwrap().parse::() 21 | .unwrap(); 22 | let fib_number = fibonacci_reccursive(input_int); 23 | writeln!(writer, "{}", fib_number); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /chapter_eleven/keep_it_simple_with_piping/input.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | sys.stdout.write("5\n") 4 | sys.stdout.write("6\n") 5 | sys.stdout.write("7\n") 6 | sys.stdout.write("8\n") 7 | sys.stdout.write("9\n") 8 | sys.stdout.write("10\n") 9 | -------------------------------------------------------------------------------- /chapter_eleven/keep_it_simple_with_piping/output.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | for i in sys.stdin.readlines(): 5 | number = i.replace('\n', '') 6 | try: 7 | processed_number = int(number) 8 | print(f"recieving: {processed_number}") 9 | except ValueError: 10 | pass 11 | -------------------------------------------------------------------------------- /chapter_eleven/keep_it_simple_with_piping/pure_python.py: -------------------------------------------------------------------------------- 1 | 2 | def recur_fib(n: int) -> int: 3 | if n <= 2: 4 | return 1 5 | else: 6 | return (recur_fib(n - 1) + 7 | recur_fib(n - 2)) 8 | 9 | 10 | for i in [5, 6, 7, 8, 9, 10, 15, 20, 25, 30]: 11 | print(recur_fib(i)) 12 | -------------------------------------------------------------------------------- /chapter_eleven/keeping-it-simple-with-rayon/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "keeping-it-simple-with-rayon" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | rayon = "1.5.1" 10 | -------------------------------------------------------------------------------- /chapter_eleven/keeping-it-simple-with-rayon/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rayon; 2 | 3 | use rayon::prelude::*; 4 | 5 | 6 | pub fn fibonacci_reccursive(n: i32) -> u64 { 7 | match n { 8 | 1 | 2 => 1, 9 | _ => fibonacci_reccursive(n - 1) + 10 | fibonacci_reccursive(n - 2) 11 | } 12 | } 13 | 14 | 15 | fn main() { 16 | // into_par_iter => 17 | let numbers: Vec = vec![6, 7, 8, 9, 10].into_par_iter().map( 18 | |x| fibonacci_reccursive(x) 19 | ).collect(); 20 | println!("{:?}", numbers); 21 | // In a lot of langues doing something like this is unthinkable but because of our borrowing rules in Rust we will not have data races 22 | } 23 | -------------------------------------------------------------------------------- /chapter_eleven/using_traits_as_opposed_to_objects/Cargo.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_eleven/using_traits_as_opposed_to_objects/Cargo.toml -------------------------------------------------------------------------------- /chapter_eleven/using_traits_as_opposed_to_objects/src/main.rs: -------------------------------------------------------------------------------- 1 | mod traits; 2 | mod objects; 3 | mod people; 4 | mod actions; 5 | 6 | use people::{Patient, Nurse, Doctor}; 7 | use objects::PatientList; 8 | use actions::{admit_patient, diagnose_patient, prescribe_meds, 9 | administer_meds, discharge_patient}; 10 | 11 | 12 | fn main() { 13 | let doctor = Doctor{name: String::from("Torath")}; 14 | let doctor_two = Doctor{name: String::from("Sergio")}; 15 | let nurse = Nurse{name: String::from("Maxwell")}; 16 | let nurse_two = Nurse{name: String::from("Nathan")}; 17 | 18 | let patient_list = PatientList { 19 | patients: vec![ 20 | Box::new(Patient{name: String::from("pestilence")}), 21 | Box::new(Patient{name: String::from("war")}), 22 | Box::new(Patient{name: String::from("famine")}), 23 | Box::new(Patient{name: String::from("death")}) 24 | ] 25 | } 26 | for i in patient_list.patients { 27 | admit_patient(&i, &nurse); 28 | diagnose_patient(&i, &doctor); 29 | prescribe_meds(&i, &doctor_two); 30 | administer_meds(&i, &nurse_two); 31 | discharge_patient(&i, &nurse); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /chapter_eleven/using_traits_as_opposed_to_objects/src/objects.rs: -------------------------------------------------------------------------------- 1 | use super::traits; 2 | use traits::PatientRole; 3 | 4 | 5 | pub struct PatientList { 6 | pub patients: Vec> 7 | } 8 | -------------------------------------------------------------------------------- /chapter_eleven/using_traits_as_opposed_to_objects/src/traits.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | pub trait Speak { 4 | fn introduce(&self) -> (); 5 | } 6 | 7 | 8 | pub trait ClinicalSkills { 9 | fn can_prescribe(&self) -> bool { 10 | return false 11 | } 12 | fn can_diagnose(&self) -> bool { 13 | return false 14 | } 15 | fn can_administer_medication(&self) -> bool { 16 | return true 17 | } 18 | } 19 | 20 | 21 | pub trait AdvancedMedical {} 22 | 23 | pub trait PatientRole { 24 | fn get_name(&self) -> String; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /chapter_five/basic_layout/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_five/basic_layout/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_five/basic_layout/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | -------------------------------------------------------------------------------- /chapter_five/basic_layout/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="flitton-fib-rs", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".flitton_fib_rs.flitton_fib_rs", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["flitton_fib_rs"], 15 | classifiers=[ 16 | "License :: OSI Approved :: MIT License", 17 | "Development Status :: 3 - Alpha", 18 | "Intended Audience :: Developers", 19 | "Programming Language :: Python", 20 | "Programming Language :: Rust", 21 | "Operating System :: POSIX", 22 | "Operating System :: MacOS :: MacOS X", 23 | ], 24 | zip_safe=False, 25 | ) 26 | -------------------------------------------------------------------------------- /chapter_five/basic_layout/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | 5 | #[pyfunction] 6 | fn say_hello() { 7 | println!("saying hello from Rust!"); 8 | } 9 | 10 | 11 | #[pymodule] 12 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 13 | m.add_wrapped(wrap_pyfunction!(say_hello)); 14 | Ok(()) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="flitton-fib-rs", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".flitton_fib_rs.flitton_fib_rs", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["flitton_fib_rs"], 15 | classifiers=[ 16 | "License :: OSI Approved :: MIT License", 17 | "Development Status :: 3 - Alpha", 18 | "Intended Audience :: Developers", 19 | "Programming Language :: Python", 20 | "Programming Language :: Rust", 21 | "Operating System :: POSIX", 22 | "Operating System :: MacOS :: MacOS X", 23 | ], 24 | entry_points={ 25 | 'console_scripts': [ 26 | 'fib-number = flitton_fib_rs.fib_number_command:fib_number_command', 27 | ], 28 | }, 29 | zip_safe=False, 30 | ) 31 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_five/fib_calcs/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | mod fib_calcs; 5 | 6 | use fib_calcs::fib_number::__pyo3_get_function_fibonacci_number; 7 | use fib_calcs::fib_numbers::__pyo3_get_function_fibonacci_numbers; 8 | pub mod fib_numbers; 9 | 10 | 11 | 12 | #[pyfunction] 13 | fn say_hello() { 14 | println!("saying hello from Rust!"); 15 | } 16 | 17 | 18 | #[pymodule] 19 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 20 | m.add_wrapped(wrap_pyfunction!(say_hello)); 21 | m.add_wrapped(wrap_pyfunction!(fibonacci_number)); 22 | m.add_wrapped(wrap_pyfunction!(fibonacci_numbers)); 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /chapter_five/testing/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_five/testing/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_five/testing/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_five/testing/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_five/testing/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_five/testing/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_five/testing/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="flitton-fib-rs", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".flitton_fib_rs.flitton_fib_rs", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["flitton_fib_rs"], 15 | classifiers=[ 16 | "License :: OSI Approved :: MIT License", 17 | "Development Status :: 3 - Alpha", 18 | "Intended Audience :: Developers", 19 | "Programming Language :: Python", 20 | "Programming Language :: Rust", 21 | "Operating System :: POSIX", 22 | "Operating System :: MacOS :: MacOS X", 23 | ], 24 | entry_points={ 25 | 'console_scripts': [ 26 | 'fib-number = flitton_fib_rs.fib_number_command:fib_number_command', 27 | ], 28 | }, 29 | zip_safe=False, 30 | ) 31 | -------------------------------------------------------------------------------- /chapter_five/testing/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_five/testing/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_five/testing/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_five/testing/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | mod fib_calcs; 5 | 6 | use fib_calcs::fib_number::__pyo3_get_function_fibonacci_number; 7 | use fib_calcs::fib_numbers::__pyo3_get_function_fibonacci_numbers; 8 | pub mod fib_numbers; 9 | 10 | 11 | 12 | #[pyfunction] 13 | fn say_hello() { 14 | println!("saying hello from Rust!"); 15 | } 16 | 17 | 18 | #[pymodule] 19 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 20 | m.add_wrapped(wrap_pyfunction!(say_hello)); 21 | m.add_wrapped(wrap_pyfunction!(fibonacci_number)); 22 | m.add_wrapped(wrap_pyfunction!(fibonacci_numbers)); 23 | Ok(()) 24 | } 25 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Maxwell Flitton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/README.md: -------------------------------------------------------------------------------- 1 | # flitton-fib-py 2 | This is a basic pip module on calculating Fibonacci numbers 3 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def say_hello() -> None: 4 | print("the Flitton Fibonacci module is saying hello") 5 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fib_calc_package/flitton_fib_py/cmd/__init__.py -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/cmd/fib_numb.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | def fib_numb() -> None: 8 | parser = argparse.ArgumentParser( 9 | description='Calculate Fibonacci numbers') 10 | parser.add_argument('--number', action='store', 11 | type=int, required=True, 12 | help="Fibonacci number to be calculated") 13 | args = parser.parse_args() 14 | print(f"Your Fibonacci number is: " 15 | f"{recurring_fibonacci_number(number=args.number)}") 16 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fib_calc_package/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/fib_calcs/fib_number.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | 4 | def recurring_fibonacci_number(number: int) -> Optional[int]: 5 | """ 6 | Calculates the fibonacci number needed. 7 | 8 | :param number: (int) the Fibonacci number to be calculated 9 | :return: (Optional[int]) the calculated fibonacci number 10 | """ 11 | if number < 0: 12 | return None 13 | elif number <= 1: 14 | return number 15 | else: 16 | return recurring_fibonacci_number(number - 1) + \ 17 | recurring_fibonacci_number(number - 2) 18 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/flitton_fib_py/fib_calcs/fib_numbers.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from .fib_number import recurring_fibonacci_number 4 | 5 | 6 | def calculate_numbers(numbers: List[int]) -> List[int]: 7 | """ 8 | Calculates a range of Fibonacci numbers from a list. 9 | 10 | :param numbers: (List[int]) the Fibonacci numbers to be calculated 11 | :return: (List[int]) the calculated Fibonacci numbers 12 | """ 13 | return [recurring_fibonacci_number(number=i) for i in numbers] 14 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | cd .. 6 | 7 | source venv/bin/activate 8 | export PYTHONPATH="./flitton_fib_py" 9 | 10 | python -m unittest discover 11 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | 4 | with open("README.md", "r") as fh: 5 | long_description = fh.read() 6 | 7 | 8 | setup( 9 | name="flitton_fib_py", 10 | version="0.0.1", 11 | author="Maxwell Flitton", 12 | author_email="maxwell@gmail.com", 13 | description="Calculates a Fibonacci number", 14 | long_description=long_description, 15 | long_description_content_type="text/markdown", 16 | url="https://github.com/maxwellflitton/flitton-fib-py", 17 | install_requires=[], 18 | packages=find_packages(exclude=("tests",)), 19 | classifiers=[ 20 | "Development Status :: 4 - Beta", 21 | "Programming Language :: Python :: 3", 22 | "Operating System :: OS Independent", 23 | ], 24 | entry_points={ 25 | 'console_scripts': [ 26 | 'fib-number = flitton_fib_py.cmd.fib_numb:fib_numb', 27 | ], 28 | }, 29 | python_requires='>=3', 30 | tests_require=['pytest'], 31 | ) 32 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fib_calc_package/tests/__init__.py -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/tests/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fib_calc_package/tests/flitton_fib_py/__init__.py -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/tests/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fib_calc_package/tests/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/tests/flitton_fib_py/fib_calcs/test_fib_number.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | 3 | from flitton_fib_py.fib_calcs.fib_number import recurring_fibonacci_number 4 | 5 | 6 | class RecurringFibNumberTest(TestCase): 7 | 8 | def test_zero(self): 9 | self.assertEqual(0, recurring_fibonacci_number(number=0)) 10 | 11 | def test_negative(self): 12 | self.assertEqual(None, recurring_fibonacci_number(number=-1)) 13 | 14 | def test_one(self): 15 | self.assertEqual(1, recurring_fibonacci_number(number=1)) 16 | 17 | def test_two(self): 18 | self.assertEqual(1, recurring_fibonacci_number(number=2)) 19 | 20 | def test_twenty(self): 21 | self.assertEqual(6765, recurring_fibonacci_number(number=20)) 22 | 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /chapter_four/fib_calc_package/tests/flitton_fib_py/fib_calcs/test_fib_numbers.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | from unittest.mock import patch, MagicMock, PropertyMock 3 | 4 | from flitton_fib_py.fib_calcs.fib_numbers import calculate_numbers 5 | 6 | 7 | class Test(TestCase): 8 | 9 | def setUp(self) -> None: 10 | pass 11 | 12 | def tearDown(self) -> None: 13 | pass 14 | 15 | @patch("flitton_fib_py.fib_calcs.fib_numbers.recurring_fibonacci_number") 16 | def test_calculate_numbers(self, mock_fib_calc): 17 | expected_outcome = [mock_fib_calc.return_value, mock_fib_calc.return_value] 18 | self.assertEqual(expected_outcome, calculate_numbers(numbers=[3, 4])) 19 | 20 | self.assertEqual(2, len(mock_fib_calc.call_args_list)) 21 | self.assertEqual({'number': 3}, mock_fib_calc.call_args_list[0][1]) 22 | self.assertEqual({'number': 4}, mock_fib_calc.call_args_list[1][1]) 23 | 24 | 25 | if __name__ == "__main__": 26 | main() 27 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/.github/workflows/publish-package.yml: -------------------------------------------------------------------------------- 1 | name: Publish Python 🐍 distributions 📦 to PyPI 2 | 3 | on: 4 | pull_request: 5 | types: [closed] 6 | branches: 7 | - main 8 | 9 | jobs: 10 | run-shell-command: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Install dependencies 15 | run: | 16 | python -m pip install --upgrade pip 17 | pip install -r requirements.txt 18 | - name: update version 19 | run: python get_latest_version.py 20 | - name: install deployment dependancies 21 | if: github.event.pull_request.merged == true 22 | run: | 23 | pip install twine 24 | pip install pexpect 25 | - name: package module 26 | if: github.event.pull_request.merged == true 27 | run: python setup.py sdist 28 | - name: deployment to pypi 29 | if: github.event.pull_request.merged == true 30 | env: 31 | TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} 32 | TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} 33 | run: | 34 | twine upload dist/* 35 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: push 4 | 5 | jobs: 6 | run-shell-command: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: Install dependencies 11 | run: | 12 | python -m pip install --upgrade pip 13 | pip install -r requirements.txt 14 | - name: run tests 15 | run: python -m unittest discover 16 | - name: run type checking 17 | run: mypy flitton_fib_py 18 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Maxwell Flitton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/README.md: -------------------------------------------------------------------------------- 1 | # flitton-fib-py 2 | This is a basic pip module on calculating Fibonacci numbers 3 | 4 | 5 | # Usage 6 | To use our module we 7 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def say_hello() -> None: 4 | print("the Flitton Fibonacci module is saying hello") 5 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fully_automated_deployment/flitton_fib_py/cmd/__init__.py -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/cmd/fib_numb.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | def fib_numb() -> None: 8 | parser = argparse.ArgumentParser( 9 | description='Calculate Fibonacci numbers') 10 | parser.add_argument('--number', action='store', 11 | type=int, required=True, 12 | help="Fibonacci number to be calculated") 13 | args = parser.parse_args() 14 | print(f"Your Fibonacci number is: " 15 | f"{recurring_fibonacci_number(number=args.number)}") 16 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fully_automated_deployment/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/fib_calcs/fib_number.py: -------------------------------------------------------------------------------- 1 | # forcing a build 2 | 3 | 4 | def recurring_fibonacci_number(number: int) -> int: 5 | """ 6 | Calculates the fibonacci number needed. 7 | 8 | :param number: (int) the Fibonacci number to be calculated 9 | :return: (Optional[int]) the calculated fibonacci number 10 | """ 11 | if number < 0: 12 | raise ValueError("Fibonacci has to be equal or above zero") 13 | elif number <= 1: 14 | return number 15 | else: 16 | return recurring_fibonacci_number(number - 1) + \ 17 | recurring_fibonacci_number(number - 2) 18 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/flitton_fib_py/fib_calcs/fib_numbers.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from .fib_number import recurring_fibonacci_number 4 | 5 | 6 | def calculate_numbers(numbers: List[int]) -> List[int]: 7 | """ 8 | Calculates a range of Fibonacci numbers from a list. 9 | 10 | :param numbers: (List[int]) the Fibonacci numbers to be calculated 11 | :return: (List[int]) the calculated Fibonacci numbers 12 | """ 13 | return [recurring_fibonacci_number(number=i) for i in numbers] 14 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/requirements.txt: -------------------------------------------------------------------------------- 1 | bleach==3.3.0 2 | certifi==2021.5.30 3 | chardet==4.0.0 4 | colorama==0.4.4 5 | dill==0.3.4 6 | docutils==0.17.1 7 | idna==2.10 8 | importlib-metadata==4.5.0 9 | keyring==23.0.1 10 | mypy==0.902 11 | mypy-extensions==0.4.3 12 | packaging==20.9 13 | pkginfo==1.7.0 14 | Pygments==2.9.0 15 | pyparsing==2.4.7 16 | PyYAML==5.4.1 17 | readme-renderer==29.0 18 | requests==2.25.1 19 | requests-toolbelt==0.9.1 20 | rfc3986==1.5.0 21 | six==1.16.0 22 | toml==0.10.2 23 | tqdm==4.61.1 24 | twine==3.4.1 25 | typing-extensions==3.10.0.0 26 | urllib3==1.26.5 27 | webencodings==0.5.1 28 | zipp==3.4.1 29 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | cd .. 6 | 7 | source venv/bin/activate 8 | export PYTHONPATH="./flitton_fib_py" 9 | 10 | python -m unittest discover 11 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fully_automated_deployment/tests/__init__.py -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/tests/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fully_automated_deployment/tests/flitton_fib_py/__init__.py -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/tests/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/fully_automated_deployment/tests/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/tests/flitton_fib_py/fib_calcs/test_fib_number.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | class RecurringFibNumberTest(TestCase): 8 | 9 | def test_zero(self): 10 | self.assertEqual( 11 | 0, recurring_fibonacci_number(number=0) 12 | ) 13 | 14 | def test_negative(self): 15 | with self.assertRaises(ValueError) as raised_error: 16 | recurring_fibonacci_number(number=-1) 17 | self.assertEqual( 18 | "Fibonacci has to be equal or above zero", 19 | str(raised_error.exception) 20 | ) 21 | 22 | def test_one(self): 23 | self.assertEqual( 24 | 1, recurring_fibonacci_number(number=1) 25 | ) 26 | 27 | def test_two(self): 28 | self.assertEqual( 29 | 1, recurring_fibonacci_number(number=2) 30 | ) 31 | 32 | def test_twenty(self): 33 | self.assertEqual( 34 | 6765, recurring_fibonacci_number(number=20) 35 | ) 36 | 37 | 38 | if __name__ == "__main__": 39 | main() 40 | -------------------------------------------------------------------------------- /chapter_four/fully_automated_deployment/tests/flitton_fib_py/fib_calcs/test_fib_numbers.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | from unittest.mock import patch 3 | 4 | from flitton_fib_py.fib_calcs.fib_numbers \ 5 | import calculate_numbers 6 | 7 | 8 | class Test(TestCase): 9 | 10 | @patch("flitton_fib_py.fib_calcs.fib_numbers." 11 | "recurring_fibonacci_number") 12 | def test_calculate_numbers(self, mock_fib_calc): 13 | expected_outcome = [mock_fib_calc.return_value, 14 | mock_fib_calc.return_value] 15 | self.assertEqual(expected_outcome, 16 | calculate_numbers(numbers=[3, 4])) 17 | 18 | self.assertEqual(2, len(mock_fib_calc.call_args_list)) 19 | self.assertEqual({'number': 3}, 20 | mock_fib_calc.call_args_list[0][1]) 21 | self.assertEqual({'number': 4}, 22 | mock_fib_calc.call_args_list[1][1]) 23 | 24 | def test_functional(self): 25 | self.assertEqual([2, 3, 5], 26 | calculate_numbers(numbers=[3, 4, 5])) 27 | 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Maxwell Flitton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/README.md: -------------------------------------------------------------------------------- 1 | # flitton-fib-py 2 | This is a basic pip module on calculating Fibonacci numbers 3 | 4 | 5 | # Usage 6 | To use our module we 7 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def say_hello() -> None: 4 | print("the Flitton Fibonacci module is saying hello") 5 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/managing_dependencies/flitton_fib_py/cmd/__init__.py -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/cmd/fib_numb.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | def fib_numb() -> None: 8 | parser = argparse.ArgumentParser( 9 | description='Calculate Fibonacci numbers') 10 | parser.add_argument('--number', action='store', 11 | type=int, required=True, 12 | help="Fibonacci number to be calculated") 13 | args = parser.parse_args() 14 | print(f"Your Fibonacci number is: " 15 | f"{recurring_fibonacci_number(number=args.number)}") 16 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/managing_dependencies/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/fib_calcs/fib_number.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | 4 | def recurring_fibonacci_number(number: int) -> Optional[int]: 5 | """ 6 | Calculates the fibonacci number needed. 7 | 8 | :param number: (int) the Fibonacci number to be calculated 9 | :return: (Optional[int]) the calculated fibonacci number 10 | """ 11 | if number < 0: 12 | return None 13 | elif number <= 1: 14 | return number 15 | else: 16 | return recurring_fibonacci_number(number - 1) + \ 17 | recurring_fibonacci_number(number - 2) 18 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/flitton_fib_py/fib_calcs/fib_numbers.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from .fib_number import recurring_fibonacci_number 4 | 5 | 6 | def calculate_numbers(numbers: List[int]) -> List[int]: 7 | """ 8 | Calculates a range of Fibonacci numbers from a list. 9 | 10 | :param numbers: (List[int]) the Fibonacci numbers to be calculated 11 | :return: (List[int]) the calculated Fibonacci numbers 12 | """ 13 | return [recurring_fibonacci_number(number=i) for i in numbers] 14 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/requirements.txt: -------------------------------------------------------------------------------- 1 | bleach==3.3.0 2 | certifi==2021.5.30 3 | chardet==4.0.0 4 | colorama==0.4.4 5 | docutils==0.17.1 6 | idna==2.10 7 | importlib-metadata==4.5.0 8 | keyring==23.0.1 9 | packaging==20.9 10 | pkginfo==1.7.0 11 | Pygments==2.9.0 12 | pyparsing==2.4.7 13 | readme-renderer==29.0 14 | requests==2.25.1 15 | requests-toolbelt==0.9.1 16 | rfc3986==1.5.0 17 | six==1.16.0 18 | tqdm==4.61.1 19 | twine==3.4.1 20 | urllib3==1.26.5 21 | webencodings==0.5.1 22 | zipp==3.4.1 23 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | cd .. 6 | 7 | source venv/bin/activate 8 | export PYTHONPATH="./flitton_fib_py" 9 | 10 | python -m unittest discover 11 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | 4 | with open("README.md", "r") as fh: 5 | long_description = fh.read() 6 | 7 | 8 | setup( 9 | name="flitton_fib_py", 10 | version="0.0.1", 11 | author="Maxwell Flitton", 12 | author_email="maxwell@gmail.com", 13 | description="Calculates a Fibonacci number", 14 | long_description=long_description, 15 | long_description_content_type="text/markdown", 16 | url="https://github.com/maxwellflitton/flitton-fib-py", 17 | install_requires=[ 18 | "PyYAML>=4.1.2", 19 | "dill>=0.2.8" 20 | ], 21 | extras_require={ 22 | 'server': ["Flask>=1.0.0"] 23 | }, 24 | packages=find_packages(exclude=("tests",)), 25 | classifiers=[ 26 | "Development Status :: 4 - Beta", 27 | "Programming Language :: Python :: 3", 28 | "Operating System :: OS Independent", 29 | ], 30 | entry_points={ 31 | 'console_scripts': [ 32 | 'fib-number = flitton_fib_py.cmd.fib_numb:fib_numb', 33 | ], 34 | }, 35 | python_requires='>=3', 36 | tests_require=['pytest'], 37 | ) 38 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/managing_dependencies/tests/__init__.py -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/tests/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/managing_dependencies/tests/flitton_fib_py/__init__.py -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/tests/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/managing_dependencies/tests/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/tests/flitton_fib_py/fib_calcs/test_fib_number.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | class RecurringFibNumberTest(TestCase): 8 | 9 | def test_zero(self): 10 | self.assertEqual( 11 | 0, recurring_fibonacci_number(number=0) 12 | ) 13 | 14 | def test_negative(self): 15 | self.assertEqual( 16 | None, recurring_fibonacci_number(number=-1) 17 | ) 18 | 19 | def test_one(self): 20 | self.assertEqual( 21 | 1, recurring_fibonacci_number(number=1) 22 | ) 23 | 24 | def test_two(self): 25 | self.assertEqual( 26 | 1, recurring_fibonacci_number(number=2) 27 | ) 28 | 29 | def test_twenty(self): 30 | self.assertEqual( 31 | 6765, recurring_fibonacci_number(number=20) 32 | ) 33 | 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /chapter_four/managing_dependencies/tests/flitton_fib_py/fib_calcs/test_fib_numbers.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | from unittest.mock import patch 3 | 4 | from flitton_fib_py.fib_calcs.fib_numbers \ 5 | import calculate_numbers 6 | 7 | 8 | class Test(TestCase): 9 | 10 | @patch("flitton_fib_py.fib_calcs.fib_numbers." 11 | "recurring_fibonacci_number") 12 | def test_calculate_numbers(self, mock_fib_calc): 13 | expected_outcome = [mock_fib_calc.return_value, 14 | mock_fib_calc.return_value] 15 | self.assertEqual(expected_outcome, 16 | calculate_numbers(numbers=[3, 4])) 17 | 18 | self.assertEqual(2, len(mock_fib_calc.call_args_list)) 19 | self.assertEqual({'number': 3}, 20 | mock_fib_calc.call_args_list[0][1]) 21 | self.assertEqual({'number': 4}, 22 | mock_fib_calc.call_args_list[1][1]) 23 | 24 | def test_functional(self): 25 | self.assertEqual([2, 3, 5], 26 | calculate_numbers(numbers=[3, 4, 5])) 27 | 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /chapter_four/module_tests/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Maxwell Flitton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_four/module_tests/README.md: -------------------------------------------------------------------------------- 1 | # flitton-fib-py 2 | This is a basic pip module on calculating Fibonacci numbers 3 | 4 | 5 | # Usage 6 | To use our module we 7 | -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def say_hello() -> None: 4 | print("the Flitton Fibonacci module is saying hello") 5 | -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/cmd/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/module_tests/flitton_fib_py/cmd/__init__.py -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/cmd/fib_numb.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | def fib_numb() -> None: 8 | parser = argparse.ArgumentParser( 9 | description='Calculate Fibonacci numbers') 10 | parser.add_argument('--number', action='store', 11 | type=int, required=True, 12 | help="Fibonacci number to be calculated") 13 | args = parser.parse_args() 14 | print(f"Your Fibonacci number is: " 15 | f"{recurring_fibonacci_number(number=args.number)}") 16 | -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/module_tests/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/fib_calcs/fib_number.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | 4 | def recurring_fibonacci_number(number: int) -> Optional[int]: 5 | """ 6 | Calculates the fibonacci number needed. 7 | 8 | :param number: (int) the Fibonacci number to be calculated 9 | :return: (Optional[int]) the calculated fibonacci number 10 | """ 11 | if number < 0: 12 | return None 13 | elif number <= 1: 14 | return number 15 | else: 16 | return recurring_fibonacci_number(number - 1) + \ 17 | recurring_fibonacci_number(number - 2) 18 | -------------------------------------------------------------------------------- /chapter_four/module_tests/flitton_fib_py/fib_calcs/fib_numbers.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from .fib_number import recurring_fibonacci_number 4 | 5 | 6 | def calculate_numbers(numbers: List[int]) -> List[int]: 7 | """ 8 | Calculates a range of Fibonacci numbers from a list. 9 | 10 | :param numbers: (List[int]) the Fibonacci numbers to be calculated 11 | :return: (List[int]) the calculated Fibonacci numbers 12 | """ 13 | return [recurring_fibonacci_number(number=i) for i in numbers] 14 | -------------------------------------------------------------------------------- /chapter_four/module_tests/scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | cd .. 6 | 7 | source venv/bin/activate 8 | export PYTHONPATH="./flitton_fib_py" 9 | 10 | python -m unittest discover 11 | -------------------------------------------------------------------------------- /chapter_four/module_tests/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | 4 | with open("README.md", "r") as fh: 5 | long_description = fh.read() 6 | 7 | 8 | setup( 9 | name="flitton_fib_py", 10 | version="0.0.1", 11 | author="Maxwell Flitton", 12 | author_email="maxwell@gmail.com", 13 | description="Calculates a Fibonacci number", 14 | long_description=long_description, 15 | long_description_content_type="text/markdown", 16 | url="https://github.com/maxwellflitton/flitton-fib-py", 17 | install_requires=[], 18 | packages=find_packages(exclude=("tests",)), 19 | classifiers=[ 20 | "Development Status :: 4 - Beta", 21 | "Programming Language :: Python :: 3", 22 | "Operating System :: OS Independent", 23 | ], 24 | entry_points={ 25 | 'console_scripts': [ 26 | 'fib-number = flitton_fib_py.cmd.fib_numb:fib_numb', 27 | ], 28 | }, 29 | python_requires='>=3', 30 | tests_require=['pytest'], 31 | ) 32 | -------------------------------------------------------------------------------- /chapter_four/module_tests/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/module_tests/tests/__init__.py -------------------------------------------------------------------------------- /chapter_four/module_tests/tests/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/module_tests/tests/flitton_fib_py/__init__.py -------------------------------------------------------------------------------- /chapter_four/module_tests/tests/flitton_fib_py/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/module_tests/tests/flitton_fib_py/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_four/module_tests/tests/flitton_fib_py/fib_calcs/test_fib_number.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | 3 | from flitton_fib_py.fib_calcs.fib_number \ 4 | import recurring_fibonacci_number 5 | 6 | 7 | class RecurringFibNumberTest(TestCase): 8 | 9 | def test_zero(self): 10 | self.assertEqual( 11 | 0, recurring_fibonacci_number(number=0) 12 | ) 13 | 14 | def test_negative(self): 15 | self.assertEqual( 16 | None, recurring_fibonacci_number(number=-1) 17 | ) 18 | 19 | def test_one(self): 20 | self.assertEqual( 21 | 1, recurring_fibonacci_number(number=1) 22 | ) 23 | 24 | def test_two(self): 25 | self.assertEqual( 26 | 1, recurring_fibonacci_number(number=2) 27 | ) 28 | 29 | def test_twenty(self): 30 | self.assertEqual( 31 | 6765, recurring_fibonacci_number(number=20) 32 | ) 33 | 34 | 35 | if __name__ == "__main__": 36 | main() 37 | -------------------------------------------------------------------------------- /chapter_four/module_tests/tests/flitton_fib_py/fib_calcs/test_fib_numbers.py: -------------------------------------------------------------------------------- 1 | from unittest import main, TestCase 2 | from unittest.mock import patch 3 | 4 | from flitton_fib_py.fib_calcs.fib_numbers \ 5 | import calculate_numbers 6 | 7 | 8 | class Test(TestCase): 9 | 10 | @patch("flitton_fib_py.fib_calcs.fib_numbers." 11 | "recurring_fibonacci_number") 12 | def test_calculate_numbers(self, mock_fib_calc): 13 | expected_outcome = [mock_fib_calc.return_value, 14 | mock_fib_calc.return_value] 15 | self.assertEqual(expected_outcome, 16 | calculate_numbers(numbers=[3, 4])) 17 | 18 | self.assertEqual(2, len(mock_fib_calc.call_args_list)) 19 | self.assertEqual({'number': 3}, 20 | mock_fib_calc.call_args_list[0][1]) 21 | self.assertEqual({'number': 4}, 22 | mock_fib_calc.call_args_list[1][1]) 23 | 24 | def test_functional(self): 25 | self.assertEqual([2, 3, 5], 26 | calculate_numbers(numbers=[3, 4, 5])) 27 | 28 | 29 | if __name__ == "__main__": 30 | main() 31 | -------------------------------------------------------------------------------- /chapter_four/packaged_module/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Maxwell Flitton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter_four/packaged_module/README.md: -------------------------------------------------------------------------------- 1 | # flitton-fib-py 2 | This is a basic pip module on calculating Fibonacci numbers 3 | -------------------------------------------------------------------------------- /chapter_four/packaged_module/flitton_fib_py/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def say_hello() -> None: 4 | print("the Flitton Fibonacci module is saying hello") 5 | -------------------------------------------------------------------------------- /chapter_four/packaged_module/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | 4 | with open("README.md", "r") as fh: 5 | long_description = fh.read() 6 | 7 | 8 | setup( 9 | name="flitton_fib_py", 10 | version="0.0.1", 11 | author="Maxwell Flitton", 12 | author_email="maxwell@gmail.com", 13 | description="Calculates a Fibonacci number", 14 | long_description=long_description, 15 | long_description_content_type="text/markdown", 16 | url="https://github.com/maxwellflitton/flitton-fib-py", 17 | install_requires=[], 18 | packages=find_packages(exclude=("tests",)), 19 | classifiers=[ 20 | "Development Status :: 4 - Beta", 21 | "Programming Language :: Python :: 3", 22 | "Operating System :: OS Independent", 23 | ], 24 | python_requires='>=3', 25 | tests_require=['pytest'], 26 | ) 27 | -------------------------------------------------------------------------------- /chapter_four/pip_setup/README.md: -------------------------------------------------------------------------------- 1 | # Packt Fibonacci 2 | This is a basic -------------------------------------------------------------------------------- /chapter_four/pip_setup/packt_fibonacci/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_four/pip_setup/packt_fibonacci/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' 13 | 14 | redis: 15 | container_name: 'main-dev-redis' 16 | image: 'redis:5.0.3' 17 | ports: 18 | - '6379:6379' 19 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | # Copy the current directory contents into the container at /app 7 | ADD . /app 8 | 9 | RUN rm ./config.yml 10 | RUN mv live_config.yml config.yml 11 | 12 | RUN apt-get update -y 13 | RUN apt-get install -y python3-dev python-dev gcc 14 | 15 | RUN pip install --upgrade pip setuptools wheel 16 | RUN pip install -r requirements.txt 17 | 18 | EXPOSE 5002 19 | 20 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 21 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_a_message_bus/src/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | QUEUE_BACKEND: "redis://localhost:6379/0" 3 | QUEUE_BROKER: "redis://localhost:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_a_message_bus/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | QUEUE_BACKEND: "redis://main_cache:6379/0" 3 | QUEUE_BROKER: "redis://main_cache:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_a_message_bus/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_a_message_bus/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.0.6 2 | billiard==3.6.4.0 3 | celery==5.2.1 4 | click==8.0.1 5 | click-didyoumean==0.3.0 6 | click-plugins==1.1.1 7 | click-repl==0.2.0 8 | Flask==2.0.1 9 | greenlet==1.1.2 10 | gunicorn==20.1.0 11 | importlib-metadata==4.6.4 12 | itsdangerous==2.0.1 13 | Jinja2==3.0.1 14 | kombu==5.2.2 15 | MarkupSafe==2.0.1 16 | prompt-toolkit==3.0.22 17 | psycopg2==2.9.2 18 | pytz==2021.3 19 | PyYAML==6.0 20 | pyyml==0.0.2 21 | six==1.16.0 22 | SQLAlchemy==1.4.27 23 | typing-extensions==3.10.0.0 24 | vine==5.0.0 25 | wcwidth==0.2.5 26 | Werkzeug==2.0.1 27 | zipp==3.5.0 28 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/task_queue/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_a_message_bus/src/task_queue/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/task_queue/engine.py: -------------------------------------------------------------------------------- 1 | from celery import Celery 2 | from config import GlobalParams 3 | 4 | 5 | def make_celery(flask_app): 6 | params = GlobalParams() 7 | celery = Celery( 8 | backend=params.get("QUEUE_BACKEND"), 9 | broker=params.get("QUEUE_BROKER") 10 | ) 11 | celery.conf.update(flask_app.config) 12 | 13 | class ContextTask(celery.Task): 14 | def __call__(self, *args, **kwargs): 15 | with flask_app.app_context(): 16 | return self.run(*args, **kwargs) 17 | 18 | celery.Task = ContextTask 19 | return celery 20 | -------------------------------------------------------------------------------- /chapter_nine/building_a_message_bus/src/task_queue/fib_calc_task.py: -------------------------------------------------------------------------------- 1 | from data_access import dal 2 | from fib_calcs.fib_calculation import FibCalculation 3 | from models.database.fib_entry import FibEntry 4 | 5 | 6 | def create_calculate_fib(input_celery): 7 | @input_celery.task() 8 | def calculate_fib(number): 9 | calculation = FibCalculation(input_number=number) 10 | fib_entry = FibEntry( 11 | input_number=calculation.input_number, 12 | calculated_number=calculation.fib_number 13 | ) 14 | dal.session.add(fib_entry) 15 | dal.session.commit() 16 | return calculate_fib 17 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/deployment/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | 4 | flask_app: 5 | container_name: fib-calculator 6 | image: "flask-fib:latest" 7 | restart: always 8 | ports: 9 | - "5002:5002" 10 | expose: 11 | - 5002 12 | 13 | nginx: 14 | container_name: 'nginx' 15 | image: "nginx:1.13.5" 16 | ports: 17 | - "80:80" 18 | links: 19 | - flask_app 20 | depends_on: 21 | - flask_app 22 | volumes: 23 | - ./nginx/nginx.conf:/etc/nginx/nginx.conf 24 | 25 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | # Copy the current directory contents into the container at /app 7 | ADD . /app 8 | 9 | RUN apt-get update -y 10 | RUN apt-get install -y python3-dev python-dev gcc 11 | 12 | RUN pip install --upgrade pip setuptools wheel 13 | RUN pip install -r requirements.txt 14 | 15 | EXPOSE 5002 16 | 17 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 18 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_flask_app/src/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | from fib_calcs.fib_calculation import FibCalculation 4 | 5 | app = Flask(__name__) 6 | 7 | 8 | @app.route("/") 9 | def home(): 10 | return "home for the fib calculator" 11 | 12 | 13 | @app.route("/calculate/") 14 | def calculate(number): 15 | calc = FibCalculation(input_number=number) 16 | return f"you entered {calc.input_number} " \ 17 | f"which has a Fibonacci number of " \ 18 | f"{calc.fib_number}" 19 | 20 | 21 | 22 | if __name__ == "__main__": 23 | app.run(use_reloader=True, port=5002, threaded=True) 24 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/building_flask_app/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_nine/building_flask_app/src/requirements.txt: -------------------------------------------------------------------------------- 1 | click==8.0.1 2 | Flask==2.0.1 3 | gunicorn==20.1.0 4 | importlib-metadata==4.6.4 5 | itsdangerous==2.0.1 6 | Jinja2==3.0.1 7 | MarkupSafe==2.0.1 8 | PyYAML==6.0 9 | pyyml==0.0.2 10 | typing-extensions==3.10.0.0 11 | Werkzeug==2.0.1 12 | zipp==3.5.0 13 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/deployment/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | 3 | flask_app: 4 | container_name: fib-calculator 5 | image: "flask-fib:latest" 6 | restart: always 7 | ports: 8 | - "5002:5002" 9 | expose: 10 | - 5002 11 | depends_on: 12 | - postgres 13 | links: 14 | - postgres 15 | 16 | nginx: 17 | container_name: 'nginx' 18 | image: "nginx:1.13.5" 19 | ports: 20 | - "80:80" 21 | links: 22 | - flask_app 23 | depends_on: 24 | - flask_app 25 | volumes: 26 | - ./nginx/nginx.conf:/etc/nginx/nginx.conf 27 | 28 | postgres: 29 | container_name: 'fib-live-postgres' 30 | image: 'postgres:11.2' 31 | restart: always 32 | ports: 33 | - '5432:5432' 34 | environment: 35 | - 'POSTGRES_USER=user' 36 | - 'POSTGRES_DB=fib' 37 | - 'POSTGRES_PASSWORD=password' 38 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | # Copy the current directory contents into the container at /app 7 | ADD . /app 8 | 9 | RUN rm ./config.yml 10 | RUN mv live_config.yml config.yml 11 | 12 | RUN apt-get update -y 13 | RUN apt-get install -y python3-dev python-dev gcc 14 | 15 | RUN pip install --upgrade pip setuptools wheel 16 | RUN pip install -r requirements.txt 17 | 18 | EXPOSE 5002 19 | 20 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 21 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/defining_our_data_access_layer/src/__init__.py -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/defining_our_data_access_layer/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/defining_our_data_access_layer/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_nine/defining_our_data_access_layer/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_nine/defining_our_data_access_layer/src/requirements.txt: -------------------------------------------------------------------------------- 1 | click==8.0.1 2 | Flask==2.0.1 3 | greenlet==1.1.2 4 | gunicorn==20.1.0 5 | importlib-metadata==4.6.4 6 | itsdangerous==2.0.1 7 | Jinja2==3.0.1 8 | MarkupSafe==2.0.1 9 | psycopg2==2.9.2 10 | PyYAML==6.0 11 | pyyml==0.0.2 12 | SQLAlchemy==1.4.27 13 | typing-extensions==3.10.0.0 14 | Werkzeug==2.0.1 15 | zipp==3.5.0 16 | -------------------------------------------------------------------------------- /chapter_one/borrowing.rs: -------------------------------------------------------------------------------- 1 | fn print(input_string: &str) { 2 | println!("{}", input_string); 3 | } 4 | fn main() { 5 | let test_string = &"Hello, World!"; 6 | print(test_string); 7 | } 8 | -------------------------------------------------------------------------------- /chapter_one/flask_app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | 3 | app = Flask(__name__) 4 | 5 | 6 | @app.route("/") 7 | def home(): 8 | return "Hello, World!" 9 | 10 | 11 | if __name__ == "__main__": 12 | app.run(debug=True) 13 | -------------------------------------------------------------------------------- /chapter_one/hello_world.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("hello world"); 3 | } 4 | -------------------------------------------------------------------------------- /chapter_one/print_function.rs: -------------------------------------------------------------------------------- 1 | fn print(input: str) { 2 | println!("{}", input); 3 | } 4 | fn main() { 5 | print("hello world"); 6 | } 7 | -------------------------------------------------------------------------------- /chapter_one/string_literals.rs: -------------------------------------------------------------------------------- 1 | fn print(input: String) { 2 | println!("{}", input); 3 | } 4 | fn main() { 5 | let string_literal = "hello world"; 6 | print(string_literal.to_string()); 7 | } 8 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/object_interface.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | from .flitton_fib_rs import object_interface 4 | 5 | 6 | class ObjectInterface: 7 | 8 | def __init__(self, number: List[int], numbers: List[List[int]]) -> None: 9 | self.number: List[int] = number 10 | self.numbers: List[List[int]] = numbers 11 | self.number_results: Optional[List[int]] = None 12 | self.numbers_results: Optional[List[List[int]]] = None 13 | 14 | def process(self) -> None: 15 | object_interface(self) 16 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_seven/adding_vectors_in_rust/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod config; 3 | -------------------------------------------------------------------------------- /chapter_seven/building_a_model_in_numpy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_seven/building_a_model_in_numpy/__init__.py -------------------------------------------------------------------------------- /chapter_seven/exploring_numpy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_seven/exploring_numpy/__init__.py -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/numpy_model.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import calculate_times, calculate_parameters 2 | 3 | 4 | class NumpyInterface: 5 | 6 | def __init__(self): 7 | self.inventory = {} 8 | 9 | def calc_times(self, distance, traffic_grade): 10 | result = calculate_times({}, distance, 11 | traffic_grade) 12 | self.inventory["car time"] = result["times"][0][0] 13 | self.inventory["truck time"] = result["times"][1][0] 14 | 15 | def calc_parameters(self, car_time, truck_time): 16 | result = calculate_parameters({}, car_time, 17 | truck_time) 18 | self.inventory["distance"] = result["parameters"][0][0] 19 | 20 | self.inventory["traffic grade"] = result["parameters"][1][0] 21 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/object_interface.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | from .flitton_fib_rs import object_interface 4 | 5 | 6 | class ObjectInterface: 7 | 8 | def __init__(self, number: List[int], numbers: List[List[int]]) -> None: 9 | self.number: List[int] = number 10 | self.numbers: List[List[int]] = numbers 11 | self.number_results: Optional[List[int]] = None 12 | self.numbers_results: Optional[List[List[int]]] = None 13 | 14 | def process(self) -> None: 15 | object_interface(self) 16 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod config; 3 | -------------------------------------------------------------------------------- /chapter_seven/numpy_model_in_rust/testing_numpy_rust_in_python.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_seven/numpy_model_in_rust/testing_numpy_rust_in_python.py -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/object_interface.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | from .flitton_fib_rs import object_interface 4 | 5 | 6 | class ObjectInterface: 7 | 8 | def __init__(self, number: List[int], numbers: List[List[int]]) -> None: 9 | self.number: List[int] = number 10 | self.numbers: List[List[int]] = numbers 11 | self.number_results: Optional[List[int]] = None 12 | self.numbers_results: Optional[List[List[int]]] = None 13 | 14 | def process(self) -> None: 15 | object_interface(self) 16 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod config; 3 | -------------------------------------------------------------------------------- /chapter_seven/using_numpy_in_rust/testing_numpy_rust_in_python.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_seven/using_numpy_in_rust/testing_numpy_rust_in_python.py -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | -------------------------------------------------------------------------------- /chapter_six/complex_data_structures/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | mod interface; 5 | mod fib_calcs; 6 | 7 | use fib_calcs::fib_number::__pyo3_get_function_fibonacci_number; 8 | use fib_calcs::fib_numbers::__pyo3_get_function_fibonacci_numbers; 9 | use interface::config::__pyo3_get_function_run_config; 10 | 11 | 12 | #[pyfunction] 13 | fn say_hello() { 14 | println!("saying hello from Rust!"); 15 | } 16 | 17 | 18 | #[pymodule] 19 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 20 | m.add_wrapped(wrap_pyfunction!(say_hello)); 21 | m.add_wrapped(wrap_pyfunction!(fibonacci_number)); 22 | m.add_wrapped(wrap_pyfunction!(fibonacci_numbers)); 23 | m.add_wrapped(wrap_pyfunction!(run_config)); 24 | Ok(()) 25 | } 26 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/class_module/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_processor; -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | -------------------------------------------------------------------------------- /chapter_six/constructing_our_own_python_objects/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | mod interface; 5 | mod fib_calcs; 6 | mod class_module; 7 | 8 | use fib_calcs::fib_number::__pyo3_get_function_fibonacci_number; 9 | use fib_calcs::fib_numbers::__pyo3_get_function_fibonacci_numbers; 10 | use interface::config::__pyo3_get_function_run_config; 11 | use class_module::fib_processor::FibProcessor; 12 | 13 | 14 | 15 | #[pyfunction] 16 | fn say_hello() { 17 | println!("saying hello from Rust!"); 18 | } 19 | 20 | 21 | #[pymodule] 22 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 23 | m.add_wrapped(wrap_pyfunction!(say_hello)); 24 | m.add_wrapped(wrap_pyfunction!(fibonacci_number)); 25 | m.add_wrapped(wrap_pyfunction!(fibonacci_numbers)); 26 | m.add_wrapped(wrap_pyfunction!(run_config)); 27 | m.add_class::()?; 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.x86_64-apple-darwin] 2 | rustflags = [ 3 | "-C", "link-arg=-undefined", 4 | "-C", "link-arg=dynamic_lookup", 5 | ] 6 | [target.aarch64-apple-darwin] 7 | rustflags = [ 8 | "-C", "link-arg=-undefined", 9 | "-C", "link-arg=dynamic_lookup", 10 | ] 11 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "flitton_fib_rs" 3 | version = "0.1.0" 4 | authors = ["Maxwell Flitton "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | 9 | [dependencies.pyo3] 10 | version = "0.13.2" 11 | features = ["extension-module"] 12 | 13 | [lib] 14 | name = "flitton_fib_rs" 15 | crate-type = ["rlib", "cdylib"] 16 | 17 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/__init__.py: -------------------------------------------------------------------------------- 1 | from .flitton_fib_rs import * 2 | from .fib_number_adapter import FlittonFibNumberAdapter 3 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/config_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import yaml 3 | import os 4 | from pprint import pprint 5 | 6 | from .flitton_fib_rs import run_config 7 | 8 | 9 | def config_number_command() -> None: 10 | parser = argparse.ArgumentParser( 11 | description='Calculate Fibonacci numbers ' 12 | 'using a config file') 13 | parser.add_argument('--path', action='store', 14 | type=str, required=True, 15 | help="path to config file") 16 | args = parser.parse_args() 17 | 18 | with open(str(os.getcwd()) + "/" + args.path) as f: 19 | config_data: dict = yaml.safe_load(f) 20 | 21 | print("Here is the config data: ") 22 | pprint(config_data) 23 | print(f"Here is the result:") 24 | pprint(run_config(config_data)) 25 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/counter.py: -------------------------------------------------------------------------------- 1 | from .singleton import Singleton 2 | 3 | 4 | class Counter(metaclass=Singleton): 5 | 6 | def __init__(self, initial_value: int = 0) -> None: 7 | self._value: int = initial_value 8 | 9 | def increase_count(self) -> None: 10 | self._value += 1 11 | 12 | @property 13 | def value(self) -> int: 14 | return self._value 15 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/fib_number_command.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from .flitton_fib_rs import fibonacci_number 3 | 4 | def fib_number_command() -> None: 5 | parser = argparse.ArgumentParser(description='Calculate Fibonacci numbers') 6 | parser.add_argument('--number', action='store', type=int, required=True, 7 | help="Fibonacci number to be calculated") 8 | args = parser.parse_args() 9 | print(f"Your Fibonacci number is: {fibonacci_number(n=args.number)}" ) 10 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/object_interface.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | from .flitton_fib_rs import object_interface 4 | 5 | 6 | class ObjectInterface: 7 | 8 | def __init__(self, number: List[int], numbers: List[List[int]]) -> None: 9 | self.number: List[int] = number 10 | self.numbers: List[List[int]] = numbers 11 | self.number_results: Optional[List[int]] = None 12 | self.numbers_results: Optional[List[List[int]]] = None 13 | 14 | def process(self) -> None: 15 | object_interface(self) 16 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/flitton_fib_rs/singleton.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Singleton(type): 4 | 5 | _instances = {} 6 | 7 | def __call__(cls, *args, **kwargs): 8 | if cls not in cls._instances: 9 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 10 | return cls._instances[cls] 11 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/src/fib_calcs/fib_number.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::pyfunction; 2 | 3 | 4 | #[pyfunction] 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | #[cfg(test)] 20 | mod fibonacci_number_tests { 21 | use super::fibonacci_number; 22 | 23 | #[test] 24 | fn test_one() { 25 | assert_eq!(fibonacci_number(1), 1); 26 | } 27 | #[test] 28 | fn test_two() { 29 | assert_eq!(fibonacci_number(2), 1); 30 | } 31 | #[test] 32 | fn test_three() { 33 | assert_eq!(fibonacci_number(3), 2); 34 | } 35 | #[test] 36 | fn test_twenty() { 37 | assert_eq!(fibonacci_number(20), 6765); 38 | } 39 | #[test] 40 | #[should_panic] 41 | fn test_0() { 42 | fibonacci_number(0); 43 | } 44 | #[test] 45 | #[should_panic] 46 | fn test_negative() { 47 | fibonacci_number(-20); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/src/fib_calcs/fib_numbers.rs: -------------------------------------------------------------------------------- 1 | use std::vec::Vec; 2 | use pyo3::prelude::pyfunction; 3 | use super::fib_number::fibonacci_number; 4 | 5 | 6 | #[pyfunction] 7 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 8 | let mut vec: Vec = Vec::new(); 9 | 10 | for n in numbers.iter() { 11 | vec.push(fibonacci_number(*n)); 12 | } 13 | return vec 14 | } 15 | 16 | 17 | #[cfg(test)] 18 | mod fibonacci_numbers_tests { 19 | 20 | use super::fibonacci_numbers; 21 | 22 | #[test] 23 | fn test_run() { 24 | let outcome = fibonacci_numbers([1, 2, 3, 4].to_vec()); 25 | assert_eq!(outcome, [1, 1, 2, 3]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/src/fib_calcs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod fib_number; 2 | pub mod fib_numbers; 3 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/src/interface/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod config; 2 | pub mod config; 3 | -------------------------------------------------------------------------------- /chapter_six/inspecting_python_objects/src/lib.rs: -------------------------------------------------------------------------------- 1 | use pyo3::prelude::*; 2 | use pyo3::wrap_pyfunction; 3 | 4 | mod interface; 5 | mod fib_calcs; 6 | 7 | use fib_calcs::fib_number::__pyo3_get_function_fibonacci_number; 8 | use fib_calcs::fib_numbers::__pyo3_get_function_fibonacci_numbers; 9 | use interface::config::__pyo3_get_function_run_config; 10 | use interface::object::__pyo3_get_function_object_interface; 11 | 12 | 13 | #[pyfunction] 14 | fn say_hello() { 15 | println!("saying hello from Rust!"); 16 | } 17 | 18 | 19 | #[pymodule] 20 | fn flitton_fib_rs(_py: Python, m: &PyModule) -> PyResult<()> { 21 | m.add_wrapped(wrap_pyfunction!(say_hello)); 22 | m.add_wrapped(wrap_pyfunction!(fibonacci_number)); 23 | m.add_wrapped(wrap_pyfunction!(fibonacci_numbers)); 24 | m.add_wrapped(wrap_pyfunction!(run_config)); 25 | m.add_wrapped(wrap_pyfunction!(object_interface)); 26 | Ok(()) 27 | } 28 | -------------------------------------------------------------------------------- /chapter_six/timing_script.py: -------------------------------------------------------------------------------- 1 | from flitton_fib_rs.flitton_fib_rs import FibProcessor 2 | import time 3 | 4 | 5 | class PythonFibProcessor: 6 | 7 | def __init__(self, number, numbers): 8 | self.number = number 9 | self.numbers = numbers 10 | self.numbers_results = None 11 | self.number_results = None 12 | self._process() 13 | 14 | def _process(self): 15 | self.numbers_results = [self.calculate_numbers(i) for i in self.numbers] 16 | self.number_results = self.calculate_numbers(self.number) 17 | 18 | def fibonacci_number(self, number): 19 | if number < 0: 20 | return None 21 | elif number <= 2: 22 | return 1 23 | else: 24 | return self.fibonacci_number(number - 1) + self.fibonacci_number(number - 2) 25 | 26 | def calculate_numbers(self, numbers): 27 | return [self.fibonacci_number(i) for i in numbers] 28 | 29 | 30 | t_one = time.time() 31 | test = FibProcessor([11, 12, 13, 14], [[11, 12], [13, 14], [15, 16]]) 32 | t_two = time.time() 33 | print(t_two - t_one) 34 | 35 | 36 | t_one = time.time() 37 | 38 | test = PythonFibProcessor([11, 12, 13, 14], [[11, 12], [13, 14], [15, 16]]) 39 | t_two = time.time() 40 | print(t_two - t_one) 41 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_db_cloning" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | diesel = { version = "1.4.4", features = ["postgres"] } 9 | dotenv = "0.15.0" 10 | 11 | [lib] 12 | name = "rust_db_cloning" 13 | crate-type = ["cdylib"] 14 | 15 | [dependencies.pyo3] 16 | version = "0.13.2" 17 | features = ["extension-module"] 18 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/diesel.toml: -------------------------------------------------------------------------------- 1 | [print_schema] 2 | file = "src/schema.rs" 3 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/rust_db_cloning/__init__.py: -------------------------------------------------------------------------------- 1 | from .rust_db_cloning import * 2 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="rust-database-cloning", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".rust_db_cloning.rust_db_cloning", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["rust_db_cloning"], 15 | zip_safe=False, 16 | ) 17 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/src/database.rs: -------------------------------------------------------------------------------- 1 | use diesel::prelude::*; 2 | use diesel::pg::PgConnection; 3 | 4 | 5 | pub fn establish_connection(url: String) -> PgConnection { 6 | PgConnection::establish(&url) 7 | .expect(&format!("Error connecting to {}", url)) 8 | } 9 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/src/models.rs: -------------------------------------------------------------------------------- 1 | use crate::schema::fib_entries; 2 | use crate::schema::alembic_version; 3 | 4 | 5 | #[derive(Queryable, Debug, Identifiable)] 6 | #[primary_key(version_num)] 7 | #[table_name="alembic_version"] 8 | pub struct AlembicVersion { 9 | pub version_num: String, 10 | } 11 | 12 | 13 | #[derive(Queryable, Debug, Identifiable)] 14 | #[table_name="fib_entries"] 15 | pub struct FibEntry { 16 | pub id: i32, 17 | pub input_number: Option, 18 | pub calculated_number: Option, 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/diesel_pip_package/src/schema.rs: -------------------------------------------------------------------------------- 1 | table! { 2 | alembic_version (version_num) { 3 | version_num -> Varchar, 4 | } 5 | } 6 | table! { 7 | fib_entries (id) { 8 | id -> Int4, 9 | input_number -> Nullable, 10 | calculated_number -> Nullable, 11 | } 12 | } 13 | allow_tables_to_appear_in_same_query!( 14 | alembic_version, 15 | fib_entries, 16 | ); 17 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' 13 | 14 | redis: 15 | container_name: 'main-dev-redis' 16 | image: 'redis:5.0.3' 17 | ports: 18 | - '6379:6379' 19 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | 6 | git clone https://github.com/maxwellflitton/flitton-fib-rs.git 7 | git clone https://github.com/maxwellflitton/rust-db-cloning.git 8 | 9 | rm -rf ./flitton-fib-rs/.git 10 | rm -rf ./rust-db-cloning/.git 11 | 12 | docker build . --no-cache -t flask-fib 13 | 14 | rm -rf ./flitton-fib-rs 15 | rm -rf ./rust-db-cloning 16 | 17 | RUN pip install ./flitton-fib-rs 18 | RUN rm -rf ./flitton-fib-rs 19 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | QUEUE_BACKEND: "redis://localhost:6379/0" 3 | QUEUE_BROKER: "redis://localhost:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | QUEUE_BACKEND: "redis://main_cache:6379/0" 3 | QUEUE_BROKER: "redis://main_cache:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.0.6 2 | billiard==3.6.4.0 3 | celery==5.2.1 4 | click==8.0.1 5 | click-didyoumean==0.3.0 6 | click-plugins==1.1.1 7 | click-repl==0.2.0 8 | Flask==2.0.1 9 | greenlet==1.1.2 10 | gunicorn==20.1.0 11 | importlib-metadata==4.6.4 12 | itsdangerous==2.0.1 13 | Jinja2==3.0.1 14 | kombu==5.2.2 15 | MarkupSafe==2.0.1 16 | prompt-toolkit==3.0.22 17 | psycopg2==2.9.2 18 | pytz==2021.3 19 | PyYAML==6.0 20 | pyyml==0.0.2 21 | six==1.16.0 22 | SQLAlchemy==1.4.27 23 | typing-extensions==3.10.0.0 24 | vine==5.0.0 25 | wcwidth==0.2.5 26 | Werkzeug==2.0.1 27 | zipp==3.5.0 28 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/task_queue/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/task_queue/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/task_queue/engine.py: -------------------------------------------------------------------------------- 1 | from celery import Celery 2 | from config import GlobalParams 3 | 4 | 5 | def make_celery(flask_app): 6 | params = GlobalParams() 7 | celery = Celery( 8 | backend=params.get("QUEUE_BACKEND"), 9 | broker=params.get("QUEUE_BROKER") 10 | ) 11 | celery.conf.update(flask_app.config) 12 | 13 | class ContextTask(celery.Task): 14 | def __call__(self, *args, **kwargs): 15 | with flask_app.app_context(): 16 | return self.run(*args, **kwargs) 17 | 18 | celery.Task = ContextTask 19 | return celery 20 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/flask_app/src/task_queue/fib_calc_task.py: -------------------------------------------------------------------------------- 1 | from data_access import dal 2 | from fib_calcs.fib_calculation import FibCalculation 3 | from models.database.fib_entry import FibEntry 4 | 5 | from config import GlobalParams 6 | from fib_calcs import calc_fib_num 7 | 8 | 9 | def create_calculate_fib(input_celery): 10 | @input_celery.task() 11 | def calculate_fib(number): 12 | params = GlobalParams() 13 | fib_number, _ = calc_fib_num(input_number=number, 14 | method=params.get( 15 | "CELERY_METHOD", 16 | "rust") 17 | ) 18 | fib_entry = FibEntry(input_number=number, 19 | calculated_number=fib_number) 20 | dal.session.add(fib_entry) 21 | dal.session.commit() 22 | return calculate_fib 23 | 24 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/pip_package/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/pip_package/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/pip_package/src/fib_calcs/enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class CalculationMethod(Enum): 5 | 6 | PYTHON = "python" 7 | RUST = "rust" 8 | -------------------------------------------------------------------------------- /chapter_ten/deploying_nightly_rust_in_rust/pip_package/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_nightly_rust_in_rust/pip_package/src/fib_calcs/fib_calculation.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' 13 | 14 | redis: 15 | container_name: 'main-dev-redis' 16 | image: 'redis:5.0.3' 17 | ports: 18 | - '6379:6379' 19 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | RUN apt-get update -y 7 | RUN apt-get install -y python3-dev python-dev gcc 8 | 9 | # setup rust 10 | RUN curl https://sh.rustup.rs -sSf | bash -s -- -y 11 | 12 | # Add .cargo/bin to PATH 13 | ENV PATH="/root/.cargo/bin:${PATH}" 14 | 15 | # Copy the current directory contents into the container at /app 16 | ADD . /app 17 | 18 | RUN rm ./config.yml 19 | RUN mv live_config.yml config.yml 20 | 21 | RUN apt-get update -y 22 | RUN apt-get install -y python3-dev python-dev gcc 23 | 24 | RUN pip install --upgrade pip setuptools wheel 25 | RUN pip install -r requirements.txt 26 | 27 | # Install the dependencies 28 | RUN pip install --upgrade pip setuptools wheel 29 | RUN pip install -r requirements.txt 30 | # RUN pip install -r git_repos.txt 31 | 32 | RUN pip install ./flitton-fib-rs 33 | RUN rm -rf ./flitton-fib-rs 34 | 35 | EXPOSE 5002 36 | 37 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 38 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/flask_app/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | 6 | git clone https://github.com/maxwellflitton/flitton-fib-rs.git 7 | cd flitton-fib-rs 8 | git checkout $1 9 | cd .. 10 | rm -rf ./flitton-fib-rs/.git 11 | 12 | docker build . --no-cache -t flask-fib 13 | rm -rf ./flitton-fib-rs 14 | 15 | RUN pip install ./flitton-fib-rs 16 | RUN rm -rf ./flitton-fib-rs 17 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | QUEUE_BACKEND: "redis://localhost:6379/0" 3 | QUEUE_BROKER: "redis://localhost:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/flask_app/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | QUEUE_BACKEND: "redis://main_cache:6379/0" 3 | QUEUE_BROKER: "redis://main_cache:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/flask_app/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/flask_app/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.0.6 2 | billiard==3.6.4.0 3 | celery==5.2.1 4 | click==8.0.1 5 | click-didyoumean==0.3.0 6 | click-plugins==1.1.1 7 | click-repl==0.2.0 8 | Flask==2.0.1 9 | greenlet==1.1.2 10 | gunicorn==20.1.0 11 | importlib-metadata==4.6.4 12 | itsdangerous==2.0.1 13 | Jinja2==3.0.1 14 | kombu==5.2.2 15 | MarkupSafe==2.0.1 16 | prompt-toolkit==3.0.22 17 | psycopg2==2.9.2 18 | pytz==2021.3 19 | PyYAML==6.0 20 | pyyml==0.0.2 21 | six==1.16.0 22 | SQLAlchemy==1.4.27 23 | typing-extensions==3.10.0.0 24 | vine==5.0.0 25 | wcwidth==0.2.5 26 | Werkzeug==2.0.1 27 | zipp==3.5.0 28 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/task_queue/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/flask_app/src/task_queue/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/task_queue/engine.py: -------------------------------------------------------------------------------- 1 | from celery import Celery 2 | from config import GlobalParams 3 | 4 | 5 | def make_celery(flask_app): 6 | params = GlobalParams() 7 | celery = Celery( 8 | backend=params.get("QUEUE_BACKEND"), 9 | broker=params.get("QUEUE_BROKER") 10 | ) 11 | celery.conf.update(flask_app.config) 12 | 13 | class ContextTask(celery.Task): 14 | def __call__(self, *args, **kwargs): 15 | with flask_app.app_context(): 16 | return self.run(*args, **kwargs) 17 | 18 | celery.Task = ContextTask 19 | return celery 20 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/flask_app/src/task_queue/fib_calc_task.py: -------------------------------------------------------------------------------- 1 | from data_access import dal 2 | from fib_calcs.fib_calculation import FibCalculation 3 | from models.database.fib_entry import FibEntry 4 | 5 | from config import GlobalParams 6 | from fib_calcs import calc_fib_num 7 | 8 | 9 | def create_calculate_fib(input_celery): 10 | @input_celery.task() 11 | def calculate_fib(number): 12 | params = GlobalParams() 13 | fib_number, _ = calc_fib_num(input_number=number, 14 | method=params.get( 15 | "CELERY_METHOD", 16 | "rust") 17 | ) 18 | fib_entry = FibEntry(input_number=number, 19 | calculated_number=fib_number) 20 | dal.session.add(fib_entry) 21 | dal.session.commit() 22 | return calculate_fib 23 | 24 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/pip_package/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/pip_package/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/pip_package/src/fib_calcs/enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class CalculationMethod(Enum): 5 | 6 | PYTHON = "python" 7 | RUST = "rust" 8 | -------------------------------------------------------------------------------- /chapter_ten/deploying_with_a_private_github_repository/pip_package/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/deploying_with_a_private_github_repository/pip_package/src/fib_calcs/fib_calculation.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' 13 | 14 | redis: 15 | container_name: 'main-dev-redis' 16 | image: 'redis:5.0.3' 17 | ports: 18 | - '6379:6379' 19 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | RUN apt-get update -y 7 | RUN apt-get install -y python3-dev python-dev gcc 8 | 9 | # setup rust 10 | RUN curl https://sh.rustup.rs -sSf | bash -s -- -y 11 | 12 | # Add .cargo/bin to PATH 13 | ENV PATH="/root/.cargo/bin:${PATH}" 14 | 15 | # Copy the current directory contents into the container at /app 16 | ADD . /app 17 | 18 | RUN rm ./config.yml 19 | RUN mv live_config.yml config.yml 20 | 21 | RUN apt-get update -y 22 | RUN apt-get install -y python3-dev python-dev gcc 23 | 24 | RUN pip install --upgrade pip setuptools wheel 25 | RUN pip install -r requirements.txt 26 | 27 | # Install the dependencies 28 | RUN pip install --upgrade pip setuptools wheel 29 | RUN pip install -r requirements.txt 30 | RUN pip install -r git_repos.txt 31 | 32 | EXPOSE 5002 33 | 34 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 35 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | QUEUE_BACKEND: "redis://localhost:6379/0" 3 | QUEUE_BROKER: "redis://localhost:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | QUEUE_BACKEND: "redis://main_cache:6379/0" 3 | QUEUE_BROKER: "redis://main_cache:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.0.6 2 | billiard==3.6.4.0 3 | celery==5.2.1 4 | click==8.0.1 5 | click-didyoumean==0.3.0 6 | click-plugins==1.1.1 7 | click-repl==0.2.0 8 | Flask==2.0.1 9 | greenlet==1.1.2 10 | gunicorn==20.1.0 11 | importlib-metadata==4.6.4 12 | itsdangerous==2.0.1 13 | Jinja2==3.0.1 14 | kombu==5.2.2 15 | MarkupSafe==2.0.1 16 | prompt-toolkit==3.0.22 17 | psycopg2==2.9.2 18 | pytz==2021.3 19 | PyYAML==6.0 20 | pyyml==0.0.2 21 | six==1.16.0 22 | SQLAlchemy==1.4.27 23 | typing-extensions==3.10.0.0 24 | vine==5.0.0 25 | wcwidth==0.2.5 26 | Werkzeug==2.0.1 27 | zipp==3.5.0 28 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/task_queue/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/task_queue/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/task_queue/engine.py: -------------------------------------------------------------------------------- 1 | from celery import Celery 2 | from config import GlobalParams 3 | 4 | 5 | def make_celery(flask_app): 6 | params = GlobalParams() 7 | celery = Celery( 8 | backend=params.get("QUEUE_BACKEND"), 9 | broker=params.get("QUEUE_BROKER") 10 | ) 11 | celery.conf.update(flask_app.config) 12 | 13 | class ContextTask(celery.Task): 14 | def __call__(self, *args, **kwargs): 15 | with flask_app.app_context(): 16 | return self.run(*args, **kwargs) 17 | 18 | celery.Task = ContextTask 19 | return celery 20 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/flask_app/src/task_queue/fib_calc_task.py: -------------------------------------------------------------------------------- 1 | from data_access import dal 2 | from fib_calcs.fib_calculation import FibCalculation 3 | from models.database.fib_entry import FibEntry 4 | 5 | from config import GlobalParams 6 | from fib_calcs import calc_fib_num 7 | 8 | 9 | def create_calculate_fib(input_celery): 10 | @input_celery.task() 11 | def calculate_fib(number): 12 | params = GlobalParams() 13 | fib_number, _ = calc_fib_num(input_number=number, 14 | method=params.get( 15 | "CELERY_METHOD", 16 | "rust") 17 | ) 18 | fib_entry = FibEntry(input_number=number, 19 | calculated_number=fib_number) 20 | dal.session.add(fib_entry) 21 | dal.session.commit() 22 | return calculate_fib 23 | 24 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/pip_package/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/pip_package/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/pip_package/src/fib_calcs/enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class CalculationMethod(Enum): 5 | 6 | PYTHON = "python" 7 | RUST = "rust" 8 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_into_flask_and_celery/pip_package/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_into_flask_and_celery/pip_package/src/fib_calcs/fib_calculation.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_db_cloning" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | diesel = { version = "1.4.4", features = ["postgres"] } 9 | dotenv = "0.15.0" 10 | 11 | [lib] 12 | name = "rust_db_cloning" 13 | crate-type = ["cdylib"] 14 | 15 | [dependencies.pyo3] 16 | version = "0.13.2" 17 | features = ["extension-module"] 18 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/diesel.toml: -------------------------------------------------------------------------------- 1 | [print_schema] 2 | file = "src/schema.rs" 3 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/rust_db_cloning/__init__.py: -------------------------------------------------------------------------------- 1 | from .rust_db_cloning import * 2 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import dist 3 | dist.Distribution().fetch_build_eggs(['setuptools_rust']) 4 | from setuptools import setup 5 | from setuptools_rust import Binding, RustExtension 6 | 7 | 8 | setup( 9 | name="rust-database-cloning", 10 | version="0.1", 11 | rust_extensions=[RustExtension( 12 | ".rust_db_cloning.rust_db_cloning", 13 | path="Cargo.toml", binding=Binding.PyO3)], 14 | packages=["rust_db_cloning"], 15 | zip_safe=False, 16 | ) 17 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/src/database.rs: -------------------------------------------------------------------------------- 1 | use diesel::prelude::*; 2 | use diesel::pg::PgConnection; 3 | 4 | 5 | pub fn establish_connection(url: String) -> PgConnection { 6 | PgConnection::establish(&url) 7 | .expect(&format!("Error connecting to {}", url)) 8 | } 9 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/src/models.rs: -------------------------------------------------------------------------------- 1 | use crate::schema::fib_entries; 2 | use crate::schema::alembic_version; 3 | 4 | 5 | #[derive(Queryable, Debug, Identifiable)] 6 | #[primary_key(version_num)] 7 | #[table_name="alembic_version"] 8 | pub struct AlembicVersion { 9 | pub version_num: String, 10 | } 11 | 12 | 13 | #[derive(Queryable, Debug, Identifiable)] 14 | #[table_name="fib_entries"] 15 | pub struct FibEntry { 16 | pub id: i32, 17 | pub input_number: Option, 18 | pub calculated_number: Option, 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/diesel_pip_package/src/schema.rs: -------------------------------------------------------------------------------- 1 | table! { 2 | alembic_version (version_num) { 3 | version_num -> Varchar, 4 | } 5 | } 6 | table! { 7 | fib_entries (id) { 8 | id -> Int4, 9 | input_number -> Nullable, 10 | calculated_number -> Nullable, 11 | } 12 | } 13 | allow_tables_to_appear_in_same_query!( 14 | alembic_version, 15 | fib_entries, 16 | ); 17 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/deployment/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log /var/log/nginx/error.log warn; 3 | 4 | 5 | events { 6 | worker_connections 512; 7 | } 8 | 9 | 10 | http { 11 | server { 12 | listen 80; 13 | 14 | location / { 15 | proxy_pass http://flask_app:5002/; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | postgres: 4 | container_name: 'fib-dev-postgres' 5 | image: 'postgres:11.2' 6 | restart: always 7 | ports: 8 | - '5432:5432' 9 | environment: 10 | - 'POSTGRES_USER=user' 11 | - 'POSTGRES_DB=fib' 12 | - 'POSTGRES_PASSWORD=password' 13 | 14 | redis: 15 | container_name: 'main-dev-redis' 16 | image: 'redis:5.0.3' 17 | ports: 18 | - '6379:6379' 19 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.6.13-stretch 2 | 3 | # Set the working directory to /app 4 | WORKDIR /app 5 | 6 | RUN apt-get update -y 7 | RUN apt-get install -y python3-dev python-dev gcc 8 | 9 | # setup rust 10 | RUN curl https://sh.rustup.rs -sSf | bash -s -- -y 11 | 12 | # Add .cargo/bin to PATH 13 | ENV PATH="/root/.cargo/bin:${PATH}" 14 | 15 | # Copy the current directory contents into the container at /app 16 | ADD . /app 17 | 18 | RUN rm ./config.yml 19 | RUN mv live_config.yml config.yml 20 | 21 | RUN apt-get update -y 22 | RUN apt-get install -y python3-dev python-dev gcc 23 | 24 | RUN pip install --upgrade pip setuptools wheel 25 | RUN pip install -r requirements.txt 26 | 27 | # Install the dependencies 28 | RUN pip install --upgrade pip setuptools wheel 29 | RUN pip install -r requirements.txt 30 | # RUN pip install -r git_repos.txt 31 | 32 | RUN pip install ./flitton-fib-rs 33 | RUN rm -rf ./flitton-fib-rs 34 | 35 | EXPOSE 5002 36 | 37 | CMD ["gunicorn", "-w 4", "-b", "0.0.0.0:5002", "app:app"] 38 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/flask_app/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/alembic/README: -------------------------------------------------------------------------------- 1 | Generic single-database configuration. -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/alembic/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" 4 | cd $SCRIPTPATH 5 | 6 | git clone https://github.com/maxwellflitton/flitton-fib-rs.git 7 | cd flitton-fib-rs 8 | git checkout $1 9 | cd .. 10 | rm -rf ./flitton-fib-rs/.git 11 | 12 | docker build . --no-cache -t flask-fib 13 | rm -rf ./flitton-fib-rs 14 | 15 | RUN pip install ./flitton-fib-rs 16 | RUN rm -rf ./flitton-fib-rs 17 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@localhost:5432/fib" 2 | QUEUE_BACKEND: "redis://localhost:6379/0" 3 | QUEUE_BROKER: "redis://localhost:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/data_access.py: -------------------------------------------------------------------------------- 1 | from flask import _app_ctx_stack 2 | from sqlalchemy import create_engine 3 | from sqlalchemy.ext.declarative import declarative_base 4 | from sqlalchemy.orm import sessionmaker, scoped_session 5 | from config import GlobalParams 6 | 7 | 8 | class DbEngine: 9 | 10 | def __init__(self) -> None: 11 | params = GlobalParams() 12 | self.base = declarative_base() 13 | self.engine = create_engine(params.get("DB_URL"), 14 | echo=True, 15 | pool_recycle=3600, 16 | pool_size=2, 17 | max_overflow=1, 18 | connect_args={ 19 | 'connect_timeout': 5 20 | }) 21 | self.session = scoped_session(sessionmaker( 22 | bind=self.engine 23 | ), scopefunc=_app_ctx_stack) 24 | self.url = params.get("DB_URL") 25 | 26 | 27 | dal = DbEngine() 28 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/fib_calcs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/flask_app/src/fib_calcs/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- 1 | class FibCalculation: 2 | 3 | def __init__(self, input_number: int) -> None: 4 | self.input_number: int = input_number 5 | self.fib_number: int = self.recur_fib( 6 | n=self.input_number 7 | ) 8 | 9 | @staticmethod 10 | def recur_fib(n: int) -> int: 11 | if n <= 1: 12 | return n 13 | else: 14 | return (FibCalculation.recur_fib(n - 1) + 15 | FibCalculation.recur_fib(n - 2)) 16 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/live_config.yml: -------------------------------------------------------------------------------- 1 | DB_URL: "postgresql://user:password@postgres:5432/fib" 2 | QUEUE_BACKEND: "redis://main_cache:6379/0" 3 | QUEUE_BROKER: "redis://main_cache:6379/0" 4 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/flask_app/src/models/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/models/database/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/flask_app/src/models/database/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/models/database/fib_entry.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from sqlalchemy import Column, Integer 3 | from data_access import dal 4 | 5 | 6 | class FibEntry(dal.base): 7 | 8 | __tablename__ = "fib_entries" 9 | 10 | id = Column(Integer, primary_key=True) 11 | input_number = Column(Integer) 12 | calculated_number = Column(Integer) 13 | 14 | @property 15 | def package(self) -> Dict[str, int]: 16 | return { 17 | "input_number": self.input_number, 18 | "calculated_number": self.calculated_number 19 | } 20 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.0.6 2 | billiard==3.6.4.0 3 | celery==5.2.1 4 | click==8.0.1 5 | click-didyoumean==0.3.0 6 | click-plugins==1.1.1 7 | click-repl==0.2.0 8 | Flask==2.0.1 9 | greenlet==1.1.2 10 | gunicorn==20.1.0 11 | importlib-metadata==4.6.4 12 | itsdangerous==2.0.1 13 | Jinja2==3.0.1 14 | kombu==5.2.2 15 | MarkupSafe==2.0.1 16 | prompt-toolkit==3.0.22 17 | psycopg2==2.9.2 18 | pytz==2021.3 19 | PyYAML==6.0 20 | pyyml==0.0.2 21 | six==1.16.0 22 | SQLAlchemy==1.4.27 23 | typing-extensions==3.10.0.0 24 | vine==5.0.0 25 | wcwidth==0.2.5 26 | Werkzeug==2.0.1 27 | zipp==3.5.0 28 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/task_queue/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/flask_app/src/task_queue/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/task_queue/engine.py: -------------------------------------------------------------------------------- 1 | from celery import Celery 2 | from config import GlobalParams 3 | 4 | 5 | def make_celery(flask_app): 6 | params = GlobalParams() 7 | celery = Celery( 8 | backend=params.get("QUEUE_BACKEND"), 9 | broker=params.get("QUEUE_BROKER") 10 | ) 11 | celery.conf.update(flask_app.config) 12 | 13 | class ContextTask(celery.Task): 14 | def __call__(self, *args, **kwargs): 15 | with flask_app.app_context(): 16 | return self.run(*args, **kwargs) 17 | 18 | celery.Task = ContextTask 19 | return celery 20 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/flask_app/src/task_queue/fib_calc_task.py: -------------------------------------------------------------------------------- 1 | from data_access import dal 2 | from fib_calcs.fib_calculation import FibCalculation 3 | from models.database.fib_entry import FibEntry 4 | 5 | from config import GlobalParams 6 | from fib_calcs import calc_fib_num 7 | 8 | 9 | def create_calculate_fib(input_celery): 10 | @input_celery.task() 11 | def calculate_fib(number): 12 | params = GlobalParams() 13 | fib_number, _ = calc_fib_num(input_number=number, 14 | method=params.get( 15 | "CELERY_METHOD", 16 | "rust") 17 | ) 18 | fib_entry = FibEntry(input_number=number, 19 | calculated_number=fib_number) 20 | dal.session.add(fib_entry) 21 | dal.session.commit() 22 | return calculate_fib 23 | 24 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/pip_package/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/pip_package/src/__init__.py -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/pip_package/src/fib_calcs/enums.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class CalculationMethod(Enum): 5 | 6 | PYTHON = "python" 7 | RUST = "rust" 8 | -------------------------------------------------------------------------------- /chapter_ten/fusing_rust_with_data_access/pip_package/src/fib_calcs/fib_calculation.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Speed-up-your-Python-with-Rust/a1841f26b7edbaa36910e3d2920e3b04a6ea8f9c/chapter_ten/fusing_rust_with_data_access/pip_package/src/fib_calcs/fib_calculation.py -------------------------------------------------------------------------------- /chapter_three/processes/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_three/processes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "processes" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | rayon="1.5.0" 11 | -------------------------------------------------------------------------------- /chapter_three/python_processes.py: -------------------------------------------------------------------------------- 1 | import time 2 | from multiprocessing import Pool 3 | 4 | 5 | def recur_fibo(n: int) -> int: 6 | if n <= 1: 7 | return n 8 | else: 9 | return (recur_fibo(n-1) + recur_fibo(n-2)) 10 | 11 | 12 | if __name__ == '__main__': 13 | start = time.time() 14 | recur_fibo(n=8) 15 | recur_fibo(n=12) 16 | recur_fibo(n=12) 17 | recur_fibo(n=20) 18 | recur_fibo(n=20) 19 | recur_fibo(n=20) 20 | recur_fibo(n=20) 21 | recur_fibo(n=28) 22 | recur_fibo(n=28) 23 | recur_fibo(n=28) 24 | recur_fibo(n=28) 25 | recur_fibo(n=36) 26 | recur_fibo(n=46) 27 | recur_fibo(n=46) 28 | recur_fibo(n=46) 29 | finish = time.time() 30 | print(f"{finish - start} has elapsed") 31 | 32 | start = time.time() 33 | with Pool(4) as p: 34 | print(p.starmap(recur_fibo, [(8,), (12,), (12,), (20,), (20,), (20,), (20,), 35 | (28,), (28,), (28,), (28,), (36,), (46,), (46,), (46,)])) 36 | finish = time.time() 37 | print(f"{finish - start} has elapsed") 38 | 39 | -------------------------------------------------------------------------------- /chapter_three/rust_processes/fib_process.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::vec::Vec; 3 | 4 | 5 | pub fn fibonacci_number(n: i32) -> u64 { 6 | if n < 0 { 7 | panic!("{} is negative!", n); 8 | } 9 | match n { 10 | 0 => panic!("zero is not a right argument to 11 | fibonacci_number!"), 12 | 1 | 2 => 1, 13 | _ => fibonacci_number(n - 1) + 14 | fibonacci_number(n - 2) 15 | } 16 | } 17 | 18 | 19 | pub fn fibonacci_numbers(numbers: Vec) -> Vec { 20 | let mut vec: Vec = Vec::new(); 21 | 22 | for n in numbers.iter() { 23 | vec.push(fibonacci_number(*n)); 24 | } 25 | return vec 26 | } 27 | 28 | 29 | 30 | fn main() { 31 | let mut inputs: Vec = Vec::new(); 32 | 33 | let args: Vec = env::args().collect(); 34 | 35 | for i in args { 36 | match i.parse::() { 37 | Ok(result) => inputs.push(result), 38 | Err(_) => (), 39 | } 40 | } 41 | 42 | let results = fibonacci_numbers(inputs); 43 | 44 | for i in results { 45 | println!("{}", i); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /chapter_three/rust_threading/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_three/rust_threading/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rust_threading" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /chapter_three/rust_threading/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_threading" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /chapter_three/threads_and_closures/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_three/threads_and_closures/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "threads_and_closures" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /chapter_three/threads_and_closures/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "threads_and_closures" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /chapter_three/threads_and_closures/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let example_closure: fn(&str) = |string_input: &str| { 3 | println!("{}", string_input); 4 | }; 5 | example_closure("this is a closure"); 6 | 7 | { 8 | let base_rate: f32 = 0.03; 9 | let calculate_interest = |loan_amount: &f32| { 10 | return loan_amount * &base_rate 11 | }; 12 | println!("the total interest to be paid is: {}", 13 | calculate_interest(&32567.6)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /chapter_two/basic_setup/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_two/basic_setup/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "itoa" 5 | version = "0.4.7" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 8 | 9 | [[package]] 10 | name = "ryu" 11 | version = "1.0.5" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 14 | 15 | [[package]] 16 | name = "serde" 17 | version = "1.0.125" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" 20 | 21 | [[package]] 22 | name = "serde_json" 23 | version = "1.0.64" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" 26 | dependencies = [ 27 | "itoa", 28 | "ryu", 29 | "serde", 30 | ] 31 | 32 | [[package]] 33 | name = "wealth_manager" 34 | version = "0.1.0" 35 | dependencies = [ 36 | "serde", 37 | "serde_json", 38 | ] 39 | -------------------------------------------------------------------------------- /chapter_two/basic_setup/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wealth_manager" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde="1.0.117" 11 | serde_json="1.0.59" 12 | -------------------------------------------------------------------------------- /chapter_two/basic_setup/src/main.rs: -------------------------------------------------------------------------------- 1 | use serde_json::{json, Value}; 2 | 3 | 4 | /// Adds two numbers together. 5 | /// 6 | /// # Arguments 7 | /// * one (i32): one of the numbers to be added 8 | /// * two (i32): one of the numbers to be added 9 | /// 10 | /// # Returns 11 | /// (i32): the sum of param one and param two 12 | /// 13 | /// # Usage 14 | /// The function can be used by the following code: 15 | /// 16 | /// ```rust 17 | /// result: i32 = add_numbers(2, 5); 18 | /// ``` 19 | fn add_numbers(one: i32, two: i32) -> i32 { 20 | return one + two 21 | } 22 | 23 | 24 | fn main() { 25 | let stock: Value = json!({ 26 | "name": "MonolithAi", 27 | "price": 43.7, 28 | "history": [19.4, 26.9, 32.5] 29 | }); 30 | 31 | println!("first price: {}", stock["history"][0]); 32 | println!("{}", stock.to_string()); 33 | } 34 | -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wealth_manager" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde="1.0.117" 11 | serde_json="1.0.59" 12 | chrono="0.4.19" 13 | -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/src/main.rs: -------------------------------------------------------------------------------- 1 | mod stocks; 2 | 3 | use stocks::{open_order, close_order}; 4 | use stocks::structs::order::Order; 5 | use stocks::enums::order_types::OrderType; 6 | 7 | 8 | fn main() { 9 | println!("hello stocks"); 10 | let mut new_order: Order = open_order(20, OrderType::Long, "bumper", 56.8, 11 | None, None); 12 | 13 | println!("the current price is: {}", &new_order.current_value()); 14 | println!("the current profit is: {}", &new_order.current_profit()); 15 | 16 | new_order.stock.update_price(43.1); 17 | println!("the current price is: {}", &new_order.current_value()); 18 | println!("the current profit is: {}", &new_order.current_profit()); 19 | 20 | new_order.stock.update_price(82.7); 21 | println!("the current price is: {}", &new_order.current_value()); 22 | println!("the current profit is: {}", &new_order.current_profit()); 23 | 24 | let profit: f32 = close_order(new_order); 25 | println!("we made {} profit", profit); 26 | } 27 | -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/src/stocks/enums/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod order_types; 2 | -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/src/stocks/enums/order_types.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | /// This enum is responsible for determining what type of order is being made. 4 | /// 5 | /// # Fields 6 | /// * Short: this is when we borrow money from the broker to buy stock, we then sell 7 | /// the stock with the intent to buy it back later, if the stock price 8 | /// drops we keep the difference making money 9 | /// * Long: this is when we buy the underlying asset with cash. If the stock price 10 | /// increases we make money when we sell 11 | pub enum OrderType { 12 | Short, 13 | Long 14 | } -------------------------------------------------------------------------------- /chapter_two/defining_interfaces/src/stocks/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod stock; 2 | pub mod order; 3 | -------------------------------------------------------------------------------- /chapter_two/interacting_with_environment/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_two/interacting_with_environment/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wealth_manager" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde="1.0.117" 11 | serde_json="1.0.59" 12 | chrono="0.4.19" 13 | rand="0.8.3" 14 | -------------------------------------------------------------------------------- /chapter_two/interacting_with_environment/src/stocks/enums/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod order_types; 2 | -------------------------------------------------------------------------------- /chapter_two/interacting_with_environment/src/stocks/enums/order_types.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | /// This enum is responsible for determining what type of order is being made. 4 | /// 5 | /// # Fields 6 | /// * Short: this is when we borrow money from the broker to buy stock, we then sell 7 | /// the stock with the intent to buy it back later, if the stock price 8 | /// drops we keep the difference making money 9 | /// * Long: this is when we buy the underlying asset with cash. If the stock price 10 | /// increases we make money when we sell 11 | pub enum OrderType { 12 | Short, 13 | Long 14 | } -------------------------------------------------------------------------------- /chapter_two/interacting_with_environment/src/stocks/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod stock; 2 | pub mod order; 3 | -------------------------------------------------------------------------------- /chapter_two/structuring_code/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /chapter_two/structuring_code/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "itoa" 5 | version = "0.4.7" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 8 | 9 | [[package]] 10 | name = "ryu" 11 | version = "1.0.5" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 14 | 15 | [[package]] 16 | name = "serde" 17 | version = "1.0.125" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" 20 | 21 | [[package]] 22 | name = "serde_json" 23 | version = "1.0.64" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" 26 | dependencies = [ 27 | "itoa", 28 | "ryu", 29 | "serde", 30 | ] 31 | 32 | [[package]] 33 | name = "wealth_manager" 34 | version = "0.1.0" 35 | dependencies = [ 36 | "serde", 37 | "serde_json", 38 | ] 39 | -------------------------------------------------------------------------------- /chapter_two/structuring_code/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wealth_manager" 3 | version = "0.1.0" 4 | authors = ["maxwellflitton"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | serde="1.0.117" 11 | serde_json="1.0.59" 12 | -------------------------------------------------------------------------------- /chapter_two/structuring_code/src/main.rs: -------------------------------------------------------------------------------- 1 | mod stocks; 2 | 3 | use stocks::structs::stock::Stock; 4 | 5 | 6 | fn main() { 7 | let stock: Stock = Stock::new("MonolithAi", 36.5); 8 | println!("here is the stock name: {}", stock.name); 9 | println!("here is the stock price: {}", stock.current_price); 10 | } 11 | -------------------------------------------------------------------------------- /chapter_two/structuring_code/src/stocks/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod structs; -------------------------------------------------------------------------------- /chapter_two/structuring_code/src/stocks/structs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod stock; 2 | mod utils; -------------------------------------------------------------------------------- /chapter_two/structuring_code/src/stocks/structs/utils.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | pub fn constructor_shout(struct_name: &str) -> () { 4 | println!("the constructor for the {} is firing", struct_name); 5 | } 6 | --------------------------------------------------------------------------------