Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{yml,yaml,json,toml}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Azure Blob Storage credentials (use one approach)

# Option 1: account name + key
AZURE_STORAGE_ACCOUNT_NAME=your_storage_account
AZURE_STORAGE_ACCOUNT_KEY=your_account_key

# Option 2: full connection string (overrides name/key when set)
# AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10

- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: CI

on:
push:
branches: [master, main]
pull_request:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.13"]

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

- name: Ruff
run: ruff check .

- name: Ruff format
run: ruff format --check .

- name: Build package
run: python -m pip install build && python -m build

- name: Tests
run: pytest --cov=get_blobs_of_file_type --cov-report=term-missing
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
.venv/
venv/
ENV/
env/

# Testing / tooling
.pytest_cache/
.coverage
htmlcov/
.ruff_cache/
.mypy_cache/

# IDE
.idea/
.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Secrets (never commit)
.env
.env.*
!.env.example
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Joel Shearon

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
99 changes: 97 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,100 @@
# GetBlobsOfFileTypePython

print("Welcome to the storage utility. Shows you blobs of a certain file type in each container you provide!")
[![CI](https://github.com/hippi345/GetBlobsOfFileTypePython/actions/workflows/ci.yml/badge.svg)](https://github.com/hippi345/GetBlobsOfFileTypePython/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

print("Usage: python main.py -s storageAccountName -k key -c [containers] -f fileType")
Command-line utility that lists blobs in Azure Blob Storage containers whose names end with a given file type (extension), and reports the total size of matching files.

## Features

- Scan one or more containers in a storage account
- Filter blobs by filename suffix (e.g. `.pdf`)
- Print per-blob sizes and a total size summary
- Credentials via CLI flags or environment variables (keys are never printed)

## Requirements

- Python 3.12 or newer
- An Azure Storage account with access to the target containers

## Setup

```bash
git clone https://github.com/hippi345/GetBlobsOfFileTypePython.git
cd GetBlobsOfFileTypePython
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
```

Copy `.env.example` to `.env` for local reference (do not commit `.env`).

## Configuration

| Variable | Description |
|----------|-------------|
| `AZURE_STORAGE_ACCOUNT_NAME` | Storage account name (used with account key) |
| `AZURE_STORAGE_ACCOUNT_KEY` | Storage account key |
| `AZURE_STORAGE_CONNECTION_STRING` | Full connection string (optional; takes precedence when set) |

CLI flags `-s` / `-k` override environment variables for account name and key when not using a connection string.

## Usage

```bash
python main.py -s myaccount -k "$AZURE_STORAGE_ACCOUNT_KEY" -c container1 container2 -f .pdf
```

Or with environment variables:

```bash
export AZURE_STORAGE_ACCOUNT_NAME=myaccount
export AZURE_STORAGE_ACCOUNT_KEY='...'
python main.py -c logs backups -f .json
```

Example output:

```
Welcome to the storage utility...
The containers are: ['logs', 'backups']
The Storage account is: myaccount
The key is: [redacted]
The file type for search is: .pdf
logs:
2024/report.pdf: 1024 bytes
Total size of .pdf files: 1024 bytes
```

Installed package entry point (optional):

```bash
get-blobs-of-file-type -c mycontainer -f .txt -s myaccount -k "$AZURE_STORAGE_ACCOUNT_KEY"
```

## Running tests

Tests run offline with mocked storage clients (no Azure credentials required):

```bash
pytest
ruff check .
ruff format --check .
```

## Project structure

```
├── get_blobs_of_file_type/ # Package: scanner + CLI
│ ├── cli.py
│ └── scanner.py
├── main.py # Backward-compatible entry point
├── tests/
├── pyproject.toml
├── .github/workflows/ci.yml
└── SECURITY.md
```

## License

MIT License — Copyright (c) 2026 Joel Shearon. See [LICENSE](LICENSE).
19 changes: 19 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Security Policy

## Supported versions

Security fixes are applied on the latest release on the default branch.

## Reporting a vulnerability

If you discover a security issue, please **do not** open a public GitHub issue with sensitive details. Contact the repository owner privately so the issue can be addressed before disclosure.

## Secrets and credentials

- Never commit storage account keys, connection strings, or other secrets to the repository.
- Configure credentials via environment variables (`AZURE_STORAGE_ACCOUNT_NAME`, `AZURE_STORAGE_ACCOUNT_KEY`, or `AZURE_STORAGE_CONNECTION_STRING`) or CLI flags at runtime.
- If a secret was ever committed to git history, rotate it immediately in Azure Portal and purge it from history if required by your policy.

## Dependencies

Dependency updates are managed via Dependabot. Run `pip install -e ".[dev]"` and keep `azure-storage-blob` current for security patches.
3 changes: 3 additions & 0 deletions get_blobs_of_file_type/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Azure Blob Storage utility to list blobs by file extension."""

__version__ = "1.0.0"
Loading
Loading