[{"content":" I&rsquo;m a huge fan of using hatch to manage my Python projects. It lets me define my projects with a single pyproject.toml file and define all of my extra environments and scripts in the same place (i.e testing \/ linting \/ docs). One big thing it&rsquo;s missing though is an integration with lockfiles.\nThe tool&rsquo;s author, @ofek, has been very clear this feature will eventually be added to hatch, but in the meantime I&rsquo;ve created a plugin that adds this functionality today: hatch-pip-compile.\nWhat is hatch-pip-compile? hatch-pip-compile is a hatch plugin that connects your hatch-managed virtual environment to a lockfile managed with pip-compile. The plugin detects whether your environment or lockfile is out to date and automatically syncs them when needed - and it&rsquo;s fast!\nWhy hatch-pip-compile? For all my projects I found myself regenerating manual lock files using complex pip-compile shell commands wired up to hatch to get a reproducible environments across machines. Every time I added or updated a package, I had to manually regenerate the lockfile. This was a huge pain and I wanted something that would automatically keep my lockfile up to date. The functionality is useful for both Python libraries and applications.\nOne of my favorite parts of the tool is that the lockfiles aren&rsquo;t in some proprietary format (no offense poetry, PDM, pipenv) so if your project has a contributor who isn&rsquo;t interested in learning how to use hatch they can simply pip install -r &lt;lockfile&gt; and get going quickly.\nHow does it work? hatch has an amazing environment plugin system that allows you to extend the functionality of your hatch environments. The plugin itself is a subclass of hatch&rsquo;s VirtualEnvironment class and overrides some methods to add the lockfile functionality:\ndependencies_in_sync sync_dependencies dependency_hash install_project \/ install_project_dev_mode There is quite a bit more to the plugin, but the above methods are the core of the implementation. Behind the scenes the plugin installs pip-tools into the virtual environment, gathers the dependencies from the pyproject.toml file, and pipes them into pip-compile to generate a lockfile.\nThe plugin writes its own header on the lockfile to ensure that it can identify when a lockfile is out of sync with the environment and update it. The plugin also supports the linking of multiple environments together to ensure that dependencies are synced to the same versions across environments (such as between your default and test environments).\nInstallation and usage of the plugin is as simple adding the following to your project&rsquo;s pyproject.toml file:\n[tool.hatch.env] requires = [ &#34;hatch-pip-compile&#34; ] [tool.hatch.envs.default] type = &#34;pip-compile&#34; Learnings from the project Lockfiles are hard Platform \/ Python Version Specific Requirements Lockfiles are a great way to ensure that your project&rsquo;s dependencies are reproducible. In the case of pip-compile, it generates a pip compatible file that can be used to install your project&rsquo;s dependencies.\nThe problem is that the lockfiles can not always be portable across Python versions and operating systems. For example, if you generate a lockfile on a Mac using pip-compile with Python 3.9, it may not be compatible with a Linux machine running Python 3.8. This is because libraries can have requirements that depend on a specific Python version or platform.\nLet&rsquo;s take the example of keyring which is a library that provides cross-platform support for storing secure secrets (it&rsquo;s also a dependency of hatch):\npywin32-ctypes&gt;=0.2.0; sys_platform==&#34;win32&#34; SecretStorage&gt;=3.2; sys_platform==&#34;linux&#34; jeepney&gt;=0.4.2; sys_platform==&#34;linux&#34; importlib_metadata &gt;= 4.11.4; python_version &lt; &#34;3.12&#34; jaraco.classes importlib_resources; python_version &lt; &#34;3.9&#34; We can see some of the requirements are platform specific, and some are Python version specific. This means that if you generate a lockfile using pip-compile on a Mac using Python 3.9, it will not see the SecretStorage requirement and will not include it on the resulting lockfile. This is a problem if you try to install the lockfile on a Linux machine running Python 3.8, and you&rsquo;re using the --no-deps flag to install your dependencies. If you&rsquo;re not using the --no-deps flag, then pip will identify that those dependencies are required for your platform \/ Python version and will install them.\nThis behavior is why the plugin uses pip instead of pip-sync to install the lockfile by default and doesn&rsquo;t use the --no-deps flag. This behavior is of course configurable, but it&rsquo;s important to understand why it&rsquo;s the default.\nBinary Availability Let&rsquo;s take another example from the pandas library, a well-known data analysis \/ manipulation package. As of this writing, the current supported versions of Python are 3.8, 3.9, 3.10, 3.11, and 3.12. If you&rsquo;re publishing a Python library that depends on pandas, you&rsquo;ll likely want to support all of these versions. However, there is not currently a version of pandas that supports all of these versions of Python and has a binary available for all of these versions too. You can sometimes build a package from source if you have the right build dependencies, but this is not always possible and usually not desirable.\nThis means that if you generate a lockfile using pip-compile on a Mac using Python 3.9, it will likely pin you on the current version of pandas (2.1.4) which does not have a binary available for 3.8. If you pinned your project to pandas==2.0.3 (the last version with a binary available for 3.8), then you would not be able to install your project on a Mac using Python 3.12 because there is no binary available for that version of Python. This means that you&rsquo;ll probably end up with something like this in your dependencies:\npandas~=2.0.3; python_version &lt; &#39;3.9&#39; pandas~=2.1.4; python_version &gt; &#39;3.8&#39; numpy~=1.24.4; python_version &lt; &#39;3.9&#39; numpy~=1.26.1; python_version &gt; &#39;3.8&#39; This will allow you to install your project on all versions of Python, but it will not be reproducible across machines. This is because the pip-compile will choose whichever version of pandas is available for its Python interpreter and exclude the other version.\nThe plugin&rsquo;s ability to support matrix environments is a great way to get around this. When a matrix environment is also a pip-compile environment, the plugin will generate a separate lockfile for each Python version.\n","permalink":"https:\/\/juftin.com\/posts\/2024-01-09-hatch-pip-compile\/","summary":"I&rsquo;m a huge fan of using hatch to manage my Python projects. It lets me define my projects with a single pyproject.toml file and define all of my extra environments and scripts in the same place (i.e testing \/ linting \/ docs). One big thing it&rsquo;s missing though is an integration with lockfiles.\nThe tool&rsquo;s author, @ofek, has been very clear this feature will eventually be added to hatch, but in the meantime I&rsquo;ve created a plugin that adds this functionality today: hatch-pip-compile.","title":"hatch's missing lockfile capability"},{"content":"llm-term Chat with LLM models directly from the command line.\nScreen Recording Your browser does not support the video tag. Installation pipx install llm-term Usage Then, you can chat with the model directly from the command line:\nllm-term llm-term works with multiple LLM providers, but by default it uses OpenAI. Most providers require extra packages to be installed, so make sure you read the Providers section below. To use a different provider, you can set the --provider \/ -p flag:\nllm-term --provider anthropic If needed, make sure you have your LLM&rsquo;s API key set as an environment variable (this can also set via the --api-key \/ -k flag in the CLI). If your LLM uses a particular environment variable for its API key, such as OPENAI_API_KEY, that will be detected automatically.\nexport LLM_API_KEY=&#34;xxxxxxxxxxxxxx&#34; Optionally, you can set a custom model. llm-term defaults to gpt-3.5-turbo (this can also set via the --model \/ -m flag in the CLI):\nexport LLM_MODEL=&#34;gpt-4&#34; Want to start the conversion directly from the command line? No problem, just pass your prompt to llm-term:\nllm-term show me python code to detect a palindrome You can also set a custom system prompt. llm-term defaults to a reasonable prompt for chatting with the model, but you can set your own prompt (this can also set via the --system \/ -s flag in the CLI):\nexport LLM_SYSTEM_MESSAGE=&#34;You are a helpful assistant who talks like a pirate.&#34; Providers OpenAI By default, llm-term uses OpenAI as your LLM provider. The default model is gpt-3.5-turbo and you can also use the OPENAI_API_KEY environment variable to set your API key.\nAnthropic Anthropic is a new LLM provider that is currently in private beta. You can request access to the beta here. The default model is claude, and you can use the ANTHROPIC_API_KEY environment variable. To use anthropic as your provider you must install the anthropic extra.\npipx install &#34;llm-term[anthropic]&#34; llm-term --provider anthropic GPT4All GPT4All is a an open source LLM provider. These models run locally on your machine, so you don&rsquo;t need to worry about API keys or rate limits. The default model is mistral-7b-openorca.Q4_0.gguf, and you can see what models are available on the GPT4All Website. Models are downloaded automatically when you first use them. To use GPT4All as your provider you must install the gpt4all extra.\npipx install &#34;llm-term[gpt4all]&#34; llm-term --provider gpt4all --model mistral-7b-openorca.Q4_0.gguf ","permalink":"https:\/\/juftin.com\/posts\/2023-09-26-llm-term\/","summary":"llm-term Chat with LLM models directly from the command line.\nScreen Recording Your browser does not support the video tag. Installation pipx install llm-term Usage Then, you can chat with the model directly from the command line:\nllm-term llm-term works with multiple LLM providers, but by default it uses OpenAI. Most providers require extra packages to be installed, so make sure you read the Providers section below. To use a different provider, you can set the --provider \/ -p flag:","title":"Chat with LLMs from the command line"},{"content":" zoo The zoo project \ud83e\udd81\ud83d\udc3c\ud83d\udc28, an asynchronous zoo API powered by FastAPI, SQLAlchemy 2.0, Pydantic v2, and Alembic. zoo is a simple yet robust API example that allows you to manage a zoo. It utilizes modern tools and practices, including a production-ready server (Uvicorn), modern SQL ORM (SQLAlchemy 2.0), data validation (Pydantic v2), and database migrations (Alembic). This project serves as an excellent starting point for building your own API, outlining the basic structure of an API project and providing examples of implementing common features.\nAsynchronous ASGI Framework (FastAPI) Production Ready Server (Uvicorn) Modern SQL ORM (SQLAlchemy 2.0) Data Validation (Pydantic v2) Authentication (fastapi-users) Database Migrations (Alembic) Docker Images (Docker) Documentation (mkdocs-material) Testing (pytest) CI\/CD (GitHub Actions) Python Environment Management (hatch) Release Automation (semantic-release) Serverless Deployment (Mangum + AWS Lambda) Worker Queues (Celery) API Caching (redis) What else? ","permalink":"https:\/\/juftin.com\/posts\/2023-08-23-zoo\/","summary":"zoo The zoo project \ud83e\udd81\ud83d\udc3c\ud83d\udc28, an asynchronous zoo API powered by FastAPI, SQLAlchemy 2.0, Pydantic v2, and Alembic. zoo is a simple yet robust API example that allows you to manage a zoo. It utilizes modern tools and practices, including a production-ready server (Uvicorn), modern SQL ORM (SQLAlchemy 2.0), data validation (Pydantic v2), and database migrations (Alembic). This project serves as an excellent starting point for building your own API, outlining the basic structure of an API project and providing examples of implementing common features.","title":"API starterpack with zoo"},{"content":"browsr browsr \ud83d\uddc2\ufe0f is a pleasant file explorer in your terminal. It&rsquo;s a command line TUI (text-based user interface) application that empowers you to browse the contents of local and remote filesystems with your keyboard or mouse.\nYou can quickly navigate through directories and peek at files whether they&rsquo;re hosted locally, in GitHub, over SSH, in AWS S3, Google Cloud Storage, or Azure Blob Storage. View code files with syntax highlighting, format JSON files, render images, convert data files to navigable datatables, and more.\nInstallation It&rsquo;s recommended to use pipx instead of pip. pipx installs the package in an isolated environment and makes it available everywhere. If you&rsquo;d like to use pip instead, just replace pipx with pip in the below command.\npipx install browsr Extra Installation If you&rsquo;re looking to use browsr on remote file systems, like GitHub or AWS S3, you&rsquo;ll need to install the remote extra. If you&rsquo;d like to browse parquet files, you&rsquo;ll need to install the parquet extra. Or, even simpler, you can install the all extra to get all the extras.\npipx install &#34;browsr[all]&#34; Usage Simply give browsr a path to a local or remote file \/ directory. Check out the Documentation for more information about the file systems supported.\nLocal browsr ~\/Downloads\/ GitHub browsr github:\/\/juftin:browsr export GITHUB_TOKEN=&#34;ghp_1234567890&#34; browsr github:\/\/juftin:browsr-private@main Cloud browsr s3:\/\/my-bucket ** Currently AWS S3, Google Cloud Storage, and Azure Blob Storage are supported.\nSSH \/ SFTP browsr ssh:\/\/username@example.com:22 ","permalink":"https:\/\/juftin.com\/posts\/2023-05-03-browsr\/","summary":"browsr browsr \ud83d\uddc2\ufe0f is a pleasant file explorer in your terminal. It&rsquo;s a command line TUI (text-based user interface) application that empowers you to browse the contents of local and remote filesystems with your keyboard or mouse.\nYou can quickly navigate through directories and peek at files whether they&rsquo;re hosted locally, in GitHub, over SSH, in AWS S3, Google Cloud Storage, or Azure Blob Storage. View code files with syntax highlighting, format JSON files, render images, convert data files to navigable datatables, and more.","title":"a friendly file browser for your terminal"},{"content":"cookiecutter-python Creating a new Python project can be a daunting task, especially when it comes to setting up all the necessary development and deployment tools. This is where my Cookiecutter Python template comes into play. This template simplifies the process of setting up a new Python project, allowing developers to focus on writing code rather than wrestling with configuration.\nWhat is Cookiecutter? Cookiecutter is a command-line utility that creates projects from project templates. With it, you can generate a new project structure with all the necessary files and directories based on a predefined template.\nKey Features hatch for managing the project&rsquo;s virtual environment and development tools ruff for code formatting and linting mypy for type checking hatch-pip-compile for dependency management + lockfiles pre-commit for managing git hooks GitHub Actions for CI\/CD MkDocs and mkdocs-material for documentation GitHub Pages for hosting documentation semantic-release and gitmoji for automated releases Publishes to PyPI and Docker Hub Getting Started To use the template, you first need to install Cookiecutter. It&rsquo;s recommended to use pipx for the installation, but you can also use pip.\npipx install cookiecutter Once Cookiecutter is installed, you can generate a new Python project using the following command:\ncookiecutter gh:juftin\/cookiecutter-python After generating the project, navigate to the root directory of your new project, create a Git repository, and install pre-commit:\ngit init pre-commit install git add . pre-commit run --all-files git add . git commit Remember to commit your lockfiles, which are created at requirements.txt and in the requirements directory. They will be created automatically when you run a hatch command in the respective environment for the first time:\nhatch run cov hatch run lint:all hatch run docs:serve git add requirements.txt requirements\/ git commit -m &#34;\ud83d\udd10 add lockfiles&#34; Managing Secrets This template uses GitHub Actions to deploy releases, documentation, and to publish artifacts to PyPI and Docker Hub. You will need to create secrets in your GitHub repository to enable these features. A .env file is provided in the project root for local development. To sync your secrets to GitHub, run the following command with the GitHub CLI:\ngh secret set --env-file .env Developing Your Project This project generates its own documentation for how to use the project&rsquo;s tools. To view the documentation locally, run:\nhatch run docs:serve Once the server is running, you can view the documentation at localhost:8080\/contributing or see a preview at juftin.com\/cookiecutter-python\/contributing.\nMy Cookiecutter Python template is an excellent tool for Python developers. It simplifies the setup process, allowing developers to jump straight into coding. Whether you&rsquo;re a seasoned developer or a beginner, this template is worth checking out.\n","permalink":"https:\/\/juftin.com\/posts\/2022-08-17-cookiecutter-template-intro\/","summary":"cookiecutter-python Creating a new Python project can be a daunting task, especially when it comes to setting up all the necessary development and deployment tools. This is where my Cookiecutter Python template comes into play. This template simplifies the process of setting up a new Python project, allowing developers to focus on writing code rather than wrestling with configuration.\nWhat is Cookiecutter? Cookiecutter is a command-line utility that creates projects from project templates.","title":"My Personal Cookiecutter Template"},{"content":" If you don&rsquo;t already know, camply is an open-source Python project that I created a little while ago that helps people to find and snag last minute cancellations at campgrounds all around the USA.\nI got the idea for camply when my partner and I took a road trip last summer. When we started planning campgrounds to stay at inside of National Parks during our trip, we quickly discovered that campsites at busy destinations like Yellowstone and Glacier are a hot commodity and totally booked out. After playing around in Chrome Developer tools on https:\/\/recreation.gov I realized that the APIs powering these websites can be used to proactively search for new availabilities to open up.\nBasically, camply works like this:\nInstall camply. pip install camply You get the ID numbers of your favorite, popular campground \/ recreation area using https:\/\/recreation.gov (you can do this with the camply CLI too, try camply --help on your commandline).\nYou use the camply CLI to search for a reservation to open up. This is pretty common on recreation.gov since their cancellation policy is generous and cheap. Check out the below command to search for campsites on weekends at Yosemite National Park (a rare find for certain coveted campgrounds).\ncamply campsites \\ --rec-area 2991 \\ --start-date 2022-06-01 \\ --end-date 2022-06-30 \\ --weekends \\ --continuous \\ --notifications pushover \\ --notify-first-try camply runs a Python process that searches for new cancellations and sends you a push notification on your phone once something becomes available.\nYou click the link on the notification and scramble to book the campsite before anybody else does.\nBoom! You&rsquo;ve just booked yourself a hard to find campsite. That&rsquo;s basically it. camply supports different notifications through email, Telegram, Pushover, and more. It also works at campgrounds in Yellowstone National Park that don&rsquo;t use recreation.gov.\ncamply been one of my favorite side projects to work on and the major part of that enjoyment is because people out there are actually using it to find spots (almost 200 Stargazers on GitHub as of writing this \ud83d\ude0d). As camply has been getting more popular the feature requests have begun to come in. Where I don&rsquo;t have time to work on those features, camply could use some architecture simplification to empower more open source contributors to develop them instead.\nAs these new projects start to pile up, I&rsquo;m beginning to ask myself: &ldquo;does camply need a large overhaul and refactor to best support this?&rdquo; If so, what&rsquo;s the best way to do that and what functionality is the most important? My end goal is a camply version 1.0.0 but for now I&rsquo;m trying to understand what to prioritize and how to make camply the best possible Python application it can be (see below for Feature Ideas and Tech Debt).\nIf you have any feature suggestions, thoughts, architecture recommendations, or interest in contributing to camply please let me know. Getting to connect with open source contributors has been the best part of building this and has made me a better developer in the process (the camping has been great too \ud83c\udfd5).\n&ndash; jf\nP.S. If you&rsquo;re interested in working on a spin-off of camply that finds and reserves last minute golfing tee times at golf courses around the world (including all the public Golf courses here in Denver, CO), let&rsquo;s chat. I&rsquo;ve got a Proof of Concept project that requires front end Python skills and I&rsquo;m looking for partners to work with on it.\ndef reintroduce_myself(name: str) -&gt; str: &#34;&#34;&#34; Go away for awhile before posting again &#34;&#34;&#34; intro = (f&#34;Hey everyone, I&#39;m {name}. &#34; &#34;I hope to have some more to say soon.&#34;) print(intro) return intro if __name__ == &#34;__main__&#34;: reintroduce_myself(name=&#34;juftin&#34;) Camply Feature Ideas and Tech Debt Support multiple, simultaneous searches in the same process #77 and #76 This idea has been brought up a couple times. My current solution is to use Docker Compose to run multiple camply docker containers in the background. Search for campsites based on attributes #63 and #75 This one is a no-brainer. People want to search for campsites that can fit their RV (or whatever equipment they might have). camply needs to be able to filter results based on a campsite&rsquo;s attributes and allowed equipment. Simplify adding new campsite providers #67 and #40 There have been a couple of requests for adding new Campsite providers (outside of Recreation.gov and Yellowstone). There is currently is an established pattern, including AbstractBaseClasses, to implement a new Campsite Booking Provider - but it&rsquo;s admittedly clunky and not super intuitive for new contributors. Search for Wilderness Permits #22 This would be a tough, yet powerful feature to implement - it uses completely different endpoints and logic from regular campgrounds Search for specific campsites inside of campgrounds #51 Done! This was a simple, but rewarding feature to implement. People can now search for their favorite campsites in their local campground Persisted data stores (like a SQLite database) to store data between searches Currently, each new camply search stores all of its data in-memory. Persisting data between searches could enable more powerful searching Webserver UI This might be fun to build if camply is to ever become useful to a non-technical audience. Being able to configure searches via a WebUI would be very useful Managed Online Service for Hosted Searches I&rsquo;m not sure if this is feasible. I&rsquo;m not interested in making money with camply, but I&rsquo;m also not interested in losing money. Hosting people&rsquo;s searches on a webiste would be great, but possibly costly and require more time involved than I have to provide. ","permalink":"https:\/\/juftin.com\/posts\/2022-05-03-lets-talk-about-camply\/","summary":"If you don&rsquo;t already know, camply is an open-source Python project that I created a little while ago that helps people to find and snag last minute cancellations at campgrounds all around the USA.\nI got the idea for camply when my partner and I took a road trip last summer. When we started planning campgrounds to stay at inside of National Parks during our trip, we quickly discovered that campsites at busy destinations like Yellowstone and Glacier are a hot commodity and totally booked out.","title":"Let's talk about camply"},{"content":" When I was setting up my portfolio site I realized that it also has some pretty nifty blogging capabilities too. Well&hellip; I guess I have a blog now.\nI&rsquo;m not typically one to channel my energy through writing so I don&rsquo;t expect to be extremely active on here but it&rsquo;s nice to have a venue where I can record my thoughts from time to time.\nIn the meantime I&rsquo;ll begin to work on putting together some more content to showcase some of my open source work.\nThanks for being here\n&ndash; jf\ndef introduce_myself(name: str) -&gt; str: &#34;&#34;&#34; Say Hi to everyone &#34;&#34;&#34; intro = (f&#34;Hey everyone, I&#39;m {name}. &#34; &#34;It&#39;s really nice to be here&#34;) print(intro) return intro if __name__ == &#34;__main__&#34;: introduce_myself(name=&#34;juftin&#34;) ","permalink":"https:\/\/juftin.com\/posts\/2022-02-08-welcome\/","summary":"When I was setting up my portfolio site I realized that it also has some pretty nifty blogging capabilities too. Well&hellip; I guess I have a blog now.\nI&rsquo;m not typically one to channel my energy through writing so I don&rsquo;t expect to be extremely active on here but it&rsquo;s nice to have a venue where I can record my thoughts from time to time.\nIn the meantime I&rsquo;ll begin to work on putting together some more content to showcase some of my open source work.","title":"I guess I have a blog now"},{"content":"design by juftin Residential design by juftin. Let&rsquo;s talk about freshening up your space.\nWelcome to my world of interior design, where creativity meets functionality. With a passion for transforming spaces into personalized havens, I am dedicated to bringing your vision to life through innovative and timeless design solutions. Let&rsquo;s collaborate to create a home that reflects your unique style and enhances your everyday living experience.\n","permalink":"https:\/\/juftin.com\/design\/","summary":"design by juftin Residential design by juftin. Let&rsquo;s talk about freshening up your space.\nWelcome to my world of interior design, where creativity meets functionality. With a passion for transforming spaces into personalized havens, I am dedicated to bringing your vision to life through innovative and timeless design solutions. Let&rsquo;s collaborate to create a home that reflects your unique style and enhances your everyday living experience.","title":""},{"content":"Project Links In no particular order, here are some links to my various open source projects.\ncamply browsr cookiecutter-python llm-term dotfiles hatch-pip-compile dotfiles lunchable lunchable-pushlunch lunchable-primelunch lunchable-splitlunch media-center textual-universal-directorytree zoo ridbPy recdotgov-client FastApp ","permalink":"https:\/\/juftin.com\/links\/","summary":"Project Links In no particular order, here are some links to my various open source projects.\ncamply browsr cookiecutter-python llm-term dotfiles hatch-pip-compile dotfiles lunchable lunchable-pushlunch lunchable-primelunch lunchable-splitlunch media-center textual-universal-directorytree zoo ridbPy recdotgov-client FastApp ","title":""},{"content":"Interested in working together? If you&rsquo;re interested in my work as a software engineer: get in touch and\/or learn more on my LinkedIn.\nWhat I&rsquo;m Working On In my free time I try to build tools and software that spark joy \u2728. Below are a few of my more public facing GitHub repositories and some details about the projects.\ncamply camply, the campsite finder \u26fa\ufe0f, is a tool to help you book an online campground. Finding reservations at sold out campgrounds can be tough. That&rsquo;s where camply comes in. It searches the APIs of Booking Services like https:\/\/recreation.gov (which works on thousands of campgrounds across the USA) to continuously check for cancellations and availabilities to pop up. Once a campsite becomes available, camply sends you a notification to book your spot!\nYou can install camply easily via pipx install camply.\nbrowsr browsr \ud83d\uddc2\ufe0f is a pleasant file explorer in your terminal. It&rsquo;s a command line TUI application that empowers you to browse the contents of local and remote directories with your keyboard or mouse. You can quickly navigate through directories and peek at files whether they&rsquo;re hosted locally, in AWS S3, Google Cloud Storage, or Azure Blob Storage. View code files with syntax highlighting, format JSON files, render images, convert CSV and Parquet files to datatables and more. Get going with all of browsr&rsquo;s superpowers with pipx install &quot;browsr[all]&quot;.\nhomelab I&rsquo;ve always been a big TV and Movies nerd. On the weekends you can find me searching RottenTomatoes for the latest certified fresh \ud83c\udf45 pick. homelab is a multi-container docker-compose application that supports every aspect of hosting your own media server at home. homelab includes everything you needto host a website for your friends and family to request new content be downloaded, services to find and securely download the latest movies and shows, and underneath it all a Plex media server to support playback of the content anywhere and on any device.\nllm-term Welcome to llm-term \ud83d\udcac, a command line utility that allows you to chat with LLM models directly from the comfort of your command line - this includes OpenAI (ChatGPT), Anthropic, and more. This tool leverages Langchain and Rich to facilitate real-time conversations with LLM models in your terminal. It enhances the user experience by streaming responses as rich text, complete with code-formatting and syntax highlighting. Get started with pipx install llm-term and stay on the command line!\nhatch-pip-compile hatch-pip-compile is the missing lockfile capability for the hatch Python project tool \ud83e\udd5a. It&rsquo;s a hatch plugin that connects your hatch-managed virtual environment to a lockfile managed with pip-compile. The plugin detects whether your environment or lockfile is out to date and automatically syncs them when needed - and it&rsquo;s fast! Get reproducible environments for your Python projects today with hatch-pip-compile\nlunchable Lunch Money is a &ldquo;delightfully simple personal finance &amp; budgeting app&rdquo; - and my current tool of choice to manage my finances. lunchable \ud83c\udf71 is a Python API Client for the Lunch Money Developer API. It\u2019s built on top of pydantic, it offers an intuitive API, a simple CLI, complete coverage of all endpoints and plugins to other external services.\ndotfiles dotfiles \ud83c\udf08 is a collection of my personal dotfiles for macOS, Linux, zsh, and everything else. It&rsquo;s a set of configuration files with an opinionated set of tools and configurations based on my personal preferences. dotfiles are a personal preference so if my files aren&rsquo;t for you, you&rsquo;ll enjoy the dev-setup \ud83d\udcd4 documentation which helps you get up and running on your own macOS or Linux machine. dotfiles can be installed with curl -fsSL https:\/\/juftin.com\/dotfiles\/get | bash.\ncookiecutter-python My personal cookiecutter template \ud83d\ude80, might be your new secret weapon for Python projects. It&rsquo;s an all-in-one development toolkit that operates seamlessly in your coding environment. Imagine managing your project&rsquo;s virtual environment and development tools with uv, managing all your development needs with task, effortlessly formatting and linting your masterpiece with ruff, and checking types using mypy. Literally all of the CI\/CD details have been taken care of. Unleash the full potential of your Python project with juftin&rsquo;s personal cookiecutter template. Get started with cookiecutter gh:juftin\/cookiecutter-python.\nzoo The zoo project \ud83e\udd81\ud83d\udc3c\ud83d\udc28, an asynchronous zoo API powered by FastAPI, SQLAlchemy 2.0, Pydantic v2, and Alembic. zoo is a simple yet robust API example that allows you to manage a zoo. It utilizes modern tools and practices, including a production-ready server (Uvicorn), modern SQL ORM (SQLAlchemy 2.0), data validation (Pydantic v2), and database migrations (Alembic). This project serves as an excellent starting point for building your own API, outlining the basic structure of an API project and providing examples of implementing common features.\n","permalink":"https:\/\/juftin.com\/work\/","summary":"Interested in working together? If you&rsquo;re interested in my work as a software engineer: get in touch and\/or learn more on my LinkedIn.\nWhat I&rsquo;m Working On In my free time I try to build tools and software that spark joy \u2728. Below are a few of my more public facing GitHub repositories and some details about the projects.\ncamply camply, the campsite finder \u26fa\ufe0f, is a tool to help you book an online campground.","title":""},{"content":" Hey, I&rsquo;m juftin (Justin Flannery) \ud83d\udc4b I&rsquo;m a software engineer and Python developer with a focus on platform engineering and machine learning operations - based out of Denver, Colorado, USA.\nMy work with data has spanned from being on the front lines as an analyst and data scientist, building out data platforms, architecting machine learning recommendation systems, and working on scalable applications as a backend and platform engineer. Currently, I work as part of an engineering team building clinical software products with AI and machine learning.\nI\u2019m very interested in machine learning operations (MLOps), big data engineering, distributed systems, large language models, and everything open source. Check out my GitHub profile to see my personal contributions to the open source community.\nWhen I\u2019m not coding you can find me camping with my partner and our son (and our two dogs), catching a bluebird day skiing in Colorado, or soaking up the sun at a bluegrass concert.\nNow is better than never.\nAlthough never is often better than right now.\n\u2013 The Zen of Python\n","permalink":"https:\/\/juftin.com\/about\/","summary":"Hey, I&rsquo;m juftin (Justin Flannery) \ud83d\udc4b I&rsquo;m a software engineer and Python developer with a focus on platform engineering and machine learning operations - based out of Denver, Colorado, USA.\nMy work with data has spanned from being on the front lines as an analyst and data scientist, building out data platforms, architecting machine learning recommendation systems, and working on scalable applications as a backend and platform engineer. Currently, I work as part of an engineering team building clinical software products with AI and machine learning.","title":"who's juftin?"}]