Tapyr features
Good and maintainable applications are never built in a day. They require a solid foundation, thoughtful design, and careful implementation. But the truth is that data scientists and developers often don’t have the time or resources to plan everything out perfectly from the start. In the end, they tend to reinvent the wheel with each new project, leading to inconsistent code quality, poor maintainability, and wasted time.
Some time ago at Appsilon, we’ve created Rhino
a framework for building high quality, enterprise-grade RShiny apps at speed. Now, we want to bring a similar solution to the Python community, focusing on Shiny for Python applications. Introducing Tapyr
- a template for building high-quality, maintainable Shiny for Python applications.
Articles in this section are two-fold:
- First, they explain the features of Tapyr and problems they solve.
- Second, they provide broader context and best practices for building high-quality applications in Python.
Tapyr Features 🧑🍳
To make it fun, let’s use a kitchen analogy.
Environment setup
You wouldn’t start cooking without setting up your kitchen first. Let’s say you have a brilliant kitchen with all the tools you need. Now you want to share the recipe with your friend. What if they don’t have spatula or a whisk? Maybe they don’t even have an oven.
The same goes for code. Setting up a development environment can be a hustle. Not everyone has the same setup, and it’s easy to run into compatibility issues.
Devcontainers and uv try to solve those issues.
- Consistent Development Environment with Devcontainers: No more “works on my machine” issues.
- Dependency Management with uv: Easy handling and setup of virtual environments.
Repository structure
A well-organized repository is like a well-organized kitchen. You know where everything is, and you can find it quickly.
Clean code organization makes it easier to maintain and extend the application. It’s easy to forget that the code is much more often read than written.
- Version Control with Git - No more back and forth emails with the code.
- Thought-Through Package Structure: Clean, maintainable code organization.
Code quality
Code quality is like the quality of the ingredients advisor. It cannot detect that you’re adding pineapple to your pizza, but it can help you avoid using expired eggs.
- Formatting with Ruff: Consistent code style.
- Linting with Ruff: Code quality checks.
- Type Checking with Pyright: Static type checking.
Validation / Testing / Quality Assurance
So you have your ingredients, you have your recipe, but how do you know if the cake is good? Or even earlier, how do you know if the cake fits in the oven? That’s where testing comes in. Checkout the Validation / Testing / Quality Assurance Overview for more details, and then:
- Unit Testing with Pytest: Write tests for your code.
- End-to-End Testing with Playwright: Automated browser testing.
- Code Coverage with pytest-cov: Monitor your test coverage.
Good practices
This section covers various best practices. For example pre-commit
hooks ensure you don’t leave the kitchen (code) dirty before you leave (commit). Or loguru
helps you to keep track of what’s happening in the kitchen. Continuous Integration with GitHub Actions is like having a sous-chef that helps you with the cooking, they recreate your recipe and tell you if it’s good (according to your tests).
- Clean Commits with Pre-Commit: Ensure clean commits.
- Continuous Integration with GitHub Actions: Automated checks for your code.
- Logging with Loguru: Enhanced debugging and monitoring.
- Prototyping with Jupyter Notebooks: Interactive development.
- Best Practice Configuration with Pydantic-Settings and Environment Variables: Configuration management.
Deployment
- Efficient Deployment to with rsconnect: Smooth deployment to Posit Connect.