This package simplifies regular common actions for quick prototyping in a user friendly way
Project description
ccfx
ccfx is a comprehensive Python package designed to streamline file and data management, geospatial analysis, NetCDF file processing, database interactions, document generation, and multimedia handling for rapid prototyping and development workflows.
Table of Contents
- Features
- Installation
- Quick Start
- Dependencies
- Usage Examples
- API Reference
- System Requirements
- Contributing
- Changelog
- License
Features
-
File Management:
- List, delete, move, copy, and count files/directories.
- Monitor file count over time.
- Save, load, and manage Python variables via pickle serialization.
- Compress directories to
.7zarchives. - Read/write text files with encoding support.
- Download files from URLs with resume and multi-connection support.
-
Geospatial Data Processing:
- Read, write, clip (by extent/feature), resample, reproject, merge, and rasterize raster data (GeoTIFF, NetCDF).
- Read, write, and clip vector data (Shapefile, GeoPackage).
- Create grids of polygons based on shapefile boundaries.
- Convert coordinates between Coordinate Reference Systems (CRS).
- Extract raster values at specific coordinates.
- Convert point lists to GeoDataFrames.
- Get vector layer bounds.
-
NetCDF File Handling:
- List variables and dimensions.
- Export NetCDF variables to GeoTIFF format (single or multiple bands).
- Calculate sum and average maps from NetCDF data across multiple files.
- Rename variables using CDO (if available).
-
Database Connectivity:
- MS SQL Server: Connect, list databases/tables, read tables (including spatial data into GeoDataFrames), write DataFrames/GeoDataFrames to tables, drop tables.
- SQLite: Connect, create/rename/drop tables, read tables (as dict, specific columns), insert data (rows, dicts, partial dicts), update values, dump tables to CSV.
-
Document & Spreadsheet Handling:
- Excel: Create
.xlsxfiles, add sheets, write data (including dates), set column widths, add scatter plot charts. - Word: Create
.docxfiles, add headings, paragraphs (with alignment), list items, formatted text (bold/italic), images, page breaks, set margins.
- Excel: Create
-
Multimedia & Web:
- Read and write MP3 metadata (ID3 tags), including album art.
- Download videos/audio from YouTube using
yt-dlp.
-
Data Analysis & Utilities:
- Calculate timeseries statistics (NSE, KGE, PBIAS, LNSE, R2, RMSE, MAE, MSE, MAPE, alpha, beta) with resampling options.
- Display dynamic progress bars.
- Check system platform information.
- Enable or disable warnings programmatically.
- Set the working directory.
Installation
Install ccfx via pip:
pip install ccfx
Note: GDAL is a core dependency and may require additional system-level installation steps. See System Requirements for details.
Quick Start
Here's a simple example to get you started with ccfx:
import ccfx
# File management
files = ccfx.listFiles("/path/to/directory", ext=".txt")
print(f"Found {len(files)} text files")
# Create and save data to Excel
excel_doc = ccfx.excel("output.xlsx")
excel_doc.create()
excel_doc.addSheet("MyData")
excel_doc.write("A1", "Hello, ccfx!")
excel_doc.save()
# Work with geospatial data
bounds = (-180, -90, 180, 90) # Global bounds
ccfx.clipRasterByExtent("input.tif", "clipped.tif", bounds)
# Download and process data
ccfx.downloadFile("https://example.com/data.zip", "./data.zip")
ccfx.compressTo7z("./my_folder", "archive.7z")
Dependencies
ccfx relies on the following libraries (automatically installed with pip):
Core Dependencies
- gdal: For geospatial raster and vector data manipulation.
- numpy: For array processing and numerical operations.
- pandas: For data manipulation and analysis.
- geopandas: Extends pandas to handle geospatial vector data.
- shapely: Provides geometric objects and operations.
- netCDF4: For working with NetCDF files.
- rasterio: Advanced raster I/O and processing.
Document & Database
- xlsxwriter: For creating and writing Excel
.xlsxfiles. - python-docx: Enables creation and manipulation of Word
.docxdocuments. - pyodbc: Enables connectivity to databases through ODBC (e.g., MS SQL Server).
- sqlalchemy: Provides SQL toolkit and ORM features for database access.
Utilities & Multimedia
- py7zr: For creating
.7zarchives. - mutagen: For reading and writing MP3 metadata (ID3 tags).
- requests: For downloading files via HTTP.
- tqdm: For displaying progress bars.
- yt-dlp: For downloading YouTube content.
- pillow: For image processing.
- scipy: For scientific computing.
- matplotlib: For plotting and visualization.
System Requirements
Python Version
- Python 3.10+ is required
GDAL Installation
GDAL can be challenging to install depending on your operating system:
Windows
# Using conda (recommended)
conda install -c conda-forge gdal
# Or using pip with pre-compiled binaries
pip install GDAL
# Alternative: If struggling with GDAL installation on Windows
pip install gdal-installer
install-gdal
macOS
# Using Homebrew
brew install gdal
pip install gdal
# Using conda
conda install -c conda-forge gdal
Linux (Ubuntu/Debian)
# Install system dependencies
sudo apt-get update
sudo apt-get install gdal-bin libgdal-dev
# Install Python bindings
pip install gdal
Docker
For a hassle-free setup, consider using the official GDAL Docker images:
docker pull ghcr.io/osgeo/gdal:ubuntu-small-latest
Usage Examples
File Management
import ccfx
# List all Python files in a directory
python_files = ccfx.listFiles("/path/to/project", ext=".py")
# Create a backup directory and copy files
ccfx.createPath("/backup/location")
ccfx.copyDirectory("/source/dir", "/backup/location")
# Compress a directory
ccfx.compressTo7z("/data/folder", "backup.7z")
# Download a file with resume capability
ccfx.downloadFile(
"https://example.com/largefile.zip",
"downloaded_file.zip",
exists_action='resume'
)
Geospatial Data Processing
import ccfx
# Clip a raster to a specific bounding box
bounds = (-74.0, 40.7, -73.9, 40.8) # NYC area
ccfx.clipRasterByExtent("satellite_image.tif", "nyc_clip.tif", bounds)
# Resample a raster to different resolution
ccfx.resampleRaster(
"high_res.tif",
"low_res.tif",
resolution=1000, # 1km resolution
resamplingMethod='bilinear'
)
# Convert coordinates between projections
lat, lon = 40.7128, -74.0060 # NYC coordinates
x, y = ccfx.convertCoordinates(lon, lat, "EPSG:4326", "EPSG:3857")
# Extract raster value at specific point
value = ccfx.extractRasterValue("elevation.tif", 40.7128, -74.0060)
print(f"Elevation at NYC: {value}")
Database Operations
import ccfx
# SQLite operations
db = ccfx.sqliteConnection("my_data.db", connect=True)
db.createTable("users", ["id INTEGER PRIMARY KEY", "name TEXT", "email TEXT"])
db.insertDict("users", {"name": "John Doe", "email": "john@example.com"})
users = db.readTableAsDict("users")
db.closeConnection()
# MS SQL Server operations
mssql = ccfx.mssql_connection("server", "username", "password", "driver")
mssql.connect()
databases = mssql.listDatabases()
df = mssql.readTable("MyDatabase", "MyTable")
mssql.close()
Document Generation
import ccfx
# Create Excel spreadsheet
excel = ccfx.excel("report.xlsx")
excel.create()
excel.addSheet("Sales Data")
excel.write("A1", "Product")
excel.write("B1", "Revenue")
excel.writeColumn("A", ["Product A", "Product B", "Product C"], start_row=2)
excel.writeColumn("B", [1000, 1500, 800], start_row=2)
excel.save()
# Create Word document
doc = ccfx.word_document("report.docx")
doc.addHeading("Monthly Report", level=1)
doc.addParagraph("This report summarizes our monthly performance.")
doc.addListItem("Revenue increased by 15%")
doc.addListItem("Customer satisfaction improved")
doc.save()
NetCDF Processing
import ccfx
# List variables in NetCDF file
variables = ccfx.netcdfVariablesList("climate_data.nc")
print("Available variables:", variables)
# Export NetCDF variable to GeoTIFF
ccfx.netcdfExportTif(
"temperature_data.nc",
"temperature",
"temp_map.tif",
band=1
)
# Calculate average from multiple NetCDF files
nc_files = ["data_2020.nc", "data_2021.nc", "data_2022.nc"]
avg_map = ccfx.netcdfAverageMap(nc_files, "precipitation")
Data Analysis
import ccfx
import pandas as pd
# Calculate timeseries statistics
observed_data = pd.read_csv("observed.csv")
simulated_data = pd.read_csv("simulated.csv")
# Combine data
data = pd.merge(observed_data, simulated_data, on='date')
# Calculate Nash-Sutcliffe Efficiency
stats = ccfx.calculateTimeseriesStats(data, observed='obs', simulated='sim')
print(f"NSE: {stats['NSE']:.3f}")
print(f"KGE: {stats['KGE']:.3f}")
print(f"R²: {stats['R2']:.3f}")
API Reference (Complete Function List)
File & Directory Management (ccfx.py)
Basic File Operations:
listFiles(path: str, ext: Optional[str] = None) -> list: Lists files in a directory, optionally filtering by extension.listAllFiles(folder: str, extension: str = "*") -> list: Recursively lists all files in a folder and its subfolders.listFolders(path: str) -> list: Lists all folders in a directory.listDirectories(path: str) -> list: Alias for listFolders.deleteFile(filePath: str, v: bool = False) -> bool: Deletes a specified file.deletePath(path: str, v: bool = False) -> bool: Deletes a directory and its contents.createPath(pathName: str, v: bool = False) -> str: Creates a directory path if it doesn't exist.getExtension(filePath: str) -> str: Gets the extension of a file.getFileBaseName(filePath: str, extension: bool = True) -> str: Gets the base name of a file.
File Copying & Moving:
copyFile(source: str, destination: str, v: bool = True) -> None: Copies a single file.copyDirectory(source: str, destination: str, recursive: bool = True, v: bool = True, filter: list = []) -> None: Copies a directory's contents.copyFolder(source: str, destination: str, v: bool = True) -> None: Alias for copyDirectory.moveDirectory(srcDir: str, destDir: str, v: bool = False) -> bool: Moves all files from source to destination directory.moveDirectoryFiles(srcDir: str, destDir: str, v: bool = False) -> bool: Moves files and subdirectories from source to destination.
File I/O Operations:
readFrom(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any: Reads ASCII files.readFile(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any: Alias for readFrom.writeTo(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool: Writes ASCII files.writeToFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool: Alias for writeTo.writeFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool: Alias for writeTo.
Compression & Archives:
compressTo7z(input_dir: str, output_file: str, compressionLevel: int = 4, excludeExt: Optional[list] = None, v: bool = False) -> None: Compresses a directory into a .7z file.uncompress(inputFile: str, outputDir: str, v: bool = False) -> None: Extracts various archive formats (.7z, .zip, .tar, etc.).uncompressFile(inputFile: str, outputDir: str, v: bool = False) -> None: Alias for uncompress.unzipFile(inputFile: str, outputDir: str, v: bool = False) -> None: Alias for uncompress.extractZip(inputFile: str, outputDir: str, v: bool = False) -> None: Alias for uncompress.extractCompressedFile(inputFile: str, outputDir: str, v: bool = False) -> None: Alias for uncompress.
File Monitoring & Statistics:
fileCount(path: str = "./", extension: str = ".*", v: bool = True) -> int: Gets the number of files in a directory with a specific extension.watchFileCount(path: str = "./", extension: str = ".*", interval: float = 0.2, duration = 3, v: bool = True) -> None: Monitors file count over time.
Variable Persistence:
pythonVariable(filename: str, option: str, variable: Any = None) -> Any: Saves ('dump') or loads ('load') Python variables using pickle.
Download Operations:
downloadFile(url: str, save_path: str, exists_action: str = 'resume', num_connections: int = 5, v: bool = False) -> None: Downloads files with resume and multi-connection support.downloadChunk(url: str, start: int, end: int, path: str) -> None: Internal function for chunked downloads.
Geospatial Data Processing (ccfx.py)
Raster Operations:
clipRasterByExtent(inFile: str, outFile: str, bounds: tuple) -> str: Clips a raster using bounding box coordinates.clipRasterByVector(inFile: str, outFile: str, vectorFile: str) -> str: Clips a raster using a vector file.resampleRaster(inFile: str, outFile: str, resolution: float, dstSRS = None, resamplingMethod = 'bilinear', replaceOutput: bool = True, v: bool = True) -> Optional[str]: Resamples a raster to a new resolution.reprojectRaster(inFile: str, outFile: str, dstProjection: str, resamplingMethod: str = 'mode') -> str: Reprojects a raster to a new CRS.mergeRasterTiles(tileList: list, outFile: str) -> str: Merges multiple raster files into one.mergeRasterFiles(tileList: list, outFile: str) -> str: Alias for mergeRasterTiles.rasterizeRaster(inFile: str, outFile: str, targetField: str, targetResolution: float) -> str: Rasterizes a vector layer based on an attribute field.rasterizeGDF(gdf: geopandas.GeoDataFrame, valueField: str, outRasterFN: str, resolution: float, isCOG: bool = True, allTouched: bool = False, profileOverrides: dict | None = None) -> str: Rasterizes a GeoDataFrame to GeoTIFF/COG.tiffWriteArray(array: numpy.ndarray, outputFile: str, geoTransform: tuple = (0, 1, 0, 0, 0, -1), projection: str = 'EPSG:4326', noData: Optional[float] = None, v: bool = False) -> gdal.Dataset: Writes a NumPy array to a GeoTIFF file.
Vector Operations:
clipVectorByExtent(inFile: str, outFile: str, bounds: tuple) -> str: Clips a vector file using bounding box coordinates.clipFeatures(inputFeaturePath: str, boundaryFeature: str, outputFeature: str, keepOnlyTypes: Optional[list] = None, v: bool = False) -> geopandas.GeoDataFrame: Clips input features by a boundary feature.getVectorBounds(grid_gdf: geopandas.GeoDataFrame) -> tuple: Gets the bounds of a GeoDataFrame.
Coordinate & Geometry Operations:
convertCoordinates(lon: float, lat: float, srcEPSG: str, dstCRS: str) -> tuple: Converts coordinates between CRSs.extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]: Extracts the raster value at a specific point.getRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]: Alias for extractRasterValue.pointsToGeodataframe(rowList: list, columnNames: list, latIndex: int, lonIndex: int, auth: str = "EPSG", code: str = "4326", outShape: str = "", format: str = "gpkg", v: bool = False, includeLatLon: bool = True) -> geopandas.GeoDataFrame: Converts a list of point coordinates to a GeoDataFrame.createPointGeometry(coords: list, proj: str = "EPSG:4326") -> geopandas.GeoDataFrame: Converts list of coordinate tuples to GeoDataFrame.createGrid(topLeft: Optional[list] = None, bottomRight: Optional[list] = None, resolution: Optional[float] = None, inputShape: Optional[str] = None, crs: str = "EPSG:4326", saveVector: Optional[str] = None) -> geopandas.GeoDataFrame: Creates a grid of polygons based on shapefile or coordinates.createPolygonFromOuterPoints(pointsGdf: geopandas.GeoDataFrame, alpha: float = 1.6, keepHoles: bool = False) -> geopandas.GeoDataFrame: Creates concave hull (alpha-shape) from points.
NetCDF File Handling (ccfx.py)
netcdfVariablesList(ncFile: str) -> list: Lists variables in a NetCDF file.netcdfVariableDimensions(ncFile: str, variable: str) -> dict: Gets dimensions and their sizes for a NetCDF variable.netcdfExportTif(ncFile: str, variable: str, outputFile: Optional[str] = None, band: Optional[int] = None, v: bool = True) -> gdal.Dataset: Exports a NetCDF variable (optionally a specific band) to GeoTIFF.netcdfAverageMap(ncFiles: list, variable: str, band: int = 1) -> numpy.ndarray: Calculates the average map from a variable across multiple NetCDF files.netcdfSumMaps(ncFiles: list, variable: str, band: int = 1) -> numpy.ndarray: Calculates the sum map from a variable across multiple NetCDF files.renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, new_var_name: str, v: bool = False) -> None: Renames a variable in a NetCDF file using CDO.
Database Connectivity
MS SQL Server (mssqlConnection.py)
Class: mssqlConnection(server, username, password, driver, trust_server_ssl=True)
__init__(server, username, password, driver, trust_server_ssl=True) -> None: Initialize connection parameters.connect(): Establish connection to server.listDatabases() -> list: List available databases.listTables(db_name=None) -> list: List tables in database.readTable(): Read table data (including spatial data into GeoDataFrames).connectDB(): Connect to specific database.dataframeToSql(): Write DataFrame/GeoDataFrame to table.dropTable(): Remove table.close(): Close connection.
SQLite (sqliteConnection.py)
Class: sqliteConnection(sqlite_database, connect=False)
__init__(sqlite_database, connect=False) -> None: Initialize database connection.connect(v=True) -> None: Establish connection.createTable(table_name, initial_field_name, data_type) -> None: Create new table.renameTable(): Rename existing table.deleteTable(): Remove table.readTableAsDict(): Read table data as dictionary.insertDict(): Insert data from dictionary.insertRow(): Insert single row.updateValue(table_name, col_name, new_value, col_where1, val_1, v=False) -> None: Update specific values.dumpCSV(): Export table to CSV.commitChanges(): Commit transactions.closeConnection(): Close connection.
Document & Spreadsheet Generation
Excel Spreadsheets (excel.py)
Class: excel(path)
__init__(path): Initialize Excel document.create(): Create new workbook.addSheet(sheet_name): Add worksheet.write(sheet_name, row, column, value): Write data to cells.writeDate(sheet_name, row, column, datetime_obj): Write date values.setDateFormat(format_string='dd/mm/yyyy'): Set date format.setColumnWidth(sheet_name, column_names, width=12): Adjust column widths.addFigure(sheet_name, x_src_sheet_name, x_start, x_end, y_src_sheet_name, y_start, y_end, position_cell="E2", chart_type='subtype'): Insert charts/graphs.save(): Save workbook.open(): Open existing file.
Word Documents (word.py)
Class: word_document(path)
__init__(path) -> None: Initialize Word document.addHeading(heading, level=2): Add document headings.addParagraph(text="", alignment='justify'): Add text paragraphs.addListItem(text="", numbers=False): Add list items.addText(text, bold=False, italic=False): Add formatted text.addImage(path_to_image, width_=16): Insert images.addPageBreak(): Insert page breaks.setMargins(): Configure page margins.save(): Save document.
Multimedia & Web (ccfx.py)
MP3 Metadata:
getMp3Metadata(fn: str, imagePath: Optional[str] = None) -> dict: Extracts ID3 metadata from an MP3 file.setMp3Metadata(fn: str, metadata: dict, imagePath: Optional[str] = None) -> bool: Writes ID3 metadata (including album art) to an MP3 file.guessMimeType(imagePath: str) -> str: Determines MIME type of image files.
YouTube Downloads:
downloadYoutubeVideo(url: str, dstDir: str, audioOnly: bool = False, cookiesFile: Optional[str] = None, dstFileName: Optional[str] = None) -> str: Downloads video or audio from a YouTube URL.parseYoutubePlaylist(playlistUrl: str) -> list[str]: Returns list of video URLs from a YouTube playlist.parseYoutubeChannelVideos(channelUrl: str, maxItems: Optional[int] = None) -> list[str]: Returns list of video URLs from a YouTube channel.
Image Processing:
removeImageColour(inPath: str, outPath: str, colour: tuple = (255, 255, 255), tolerance: int = 30) -> None: Removes a specific color from an image.makeTransparent(inPath: str, outPath: str, colour: tuple = (255, 255, 255), tolerance: int = 30) -> None: Makes pixels in an image transparent.
Video Processing:
correctFisheye(inputFile: str, outputFile: str = '', k1: float = -0.1, k2: float = 0.05, cx: float = 0.5, cy: float = 0.5, crf: int = 20) -> str: Corrects fisheye distortion in videos.correctLens(inputFile: str, outputFile: str = '', k1: float = -0.1, k2: float = 0.05, cx: float = 0.5, cy: float = 0.5, crf: int = 20) -> str: Alias for correctFisheye.
Data Analysis & Statistics (ccfx.py)
Timeseries Analysis:
calculateTimeseriesStats(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> dict: Calculates comprehensive statistics between observed and simulated timeseries.getNSE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Nash-Sutcliffe Efficiency.getKGE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Kling-Gupta Efficiency.getPBIAS(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Percent Bias.getLNSE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Log Nash-Sutcliffe Efficiency.getR2(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates R-squared.getRMSE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Root Mean Square Error.getMAE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Mean Absolute Error.getMSE(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> float: Calculates Mean Square Error.getTimeseriesStats(data: pandas.DataFrame, observed: Optional[str] = None, simulated: Optional[str] = None, resample: Optional[str] = None) -> dict: Alias for calculateTimeseriesStats.
SWAT+ Integration:
readSWATPlusOutputs(filePath: str, column: Optional[str] = None, unit: Optional[int] = None, gis_id: Optional[int] = None, name: Optional[str] = None, coerceNumeric: bool = True) -> Optional[pandas.DataFrame]: Reads SWAT+ output files with filtering capabilities.runSWATPlus(txtinoutDir: str, finalDir: str, executablePath: str = "swatplus", v: bool = True) -> None: Runs SWAT+ model with progress monitoring.
Utility Functions (ccfx.py)
Progress & Display:
progressBar(count: int, total: int, message: str = "") -> None: Displays a simple console progress bar.showProgress(count: int, end: int, message: str, barLength: int = 100) -> None: Displays a detailed console progress bar.dualProgress(primaryCount: int, primaryEnd: int, secondaryCount: int, secondaryEnd: int, barLength: int = 40, message: str = '') -> None: Displays two progress bars simultaneously.
System & Environment:
systemPlatform() -> str: Gets the system platform.setHomeDir(path: str) -> str: Sets the working directory to script location.ignoreWarnings(ignore: bool = True, v: bool = False) -> None: Suppresses or enables Python warnings.
Text & String Processing:
formatStringBlock(input_str: str, max_chars: int = 70) -> str: Formats a string into a block of text with maximum characters per line.formatTimedelta(delta: timedelta) -> str: Formats a timedelta duration to readable format.
Mathematical Utilities:
isBetween(number: float, a: float, b: float) -> bool: Returns True if number is between a and b.
Notifications:
alert(message: str, server: str = "http://ntfy.sh", topic: str = "pythonAlerts", attachment: Optional[str] = None, messageTitle: str = "info", priority: int = None, tags: list = [], printIt: bool = True, v: bool = False) -> bool: Sends notifications to external servers.
Contributing
Contributions are welcome! Please fork the repository, make your changes, and submit a pull request. Ensure code is well-documented and includes tests where applicable.
Development Setup
git clone https://github.com/celray/ccfx.git
cd ccfx
pip install -e .
Version Management
To automatically update the version in README.md based on pyproject.toml:
# Make the script executable (if not already)
chmod +x updateReadmeVersion.py
# Run the version update script
./updateReadmeVersion.py
You can also integrate this into your build process by adding it to your CI/CD pipeline or as a pre-commit hook.
Testing
Please ensure your changes don't break existing functionality and add tests for new features.
Changelog
Version 1.1.2 (Current)
- Enhanced geospatial processing capabilities
- Improved database connectivity options
- Added comprehensive multimedia support
- Better error handling and documentation
For detailed release notes, visit the Releases page.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author: Celray James CHAWANDA
Email: celray@chawanda.com
GitHub: @celray
Package Homepage: https://github.com/celray/ccfx
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ccfx-1.1.2.tar.gz.
File metadata
- Download URL: ccfx-1.1.2.tar.gz
- Upload date:
- Size: 50.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a184483e30a037b813bffe5e3d00df7f050048aa472abbdba0bf69bcc8d7643f
|
|
| MD5 |
9b35e23f171a900c628c7d551a38c9d3
|
|
| BLAKE2b-256 |
f744f665d367d96b7fb9e02007932fcef43a9b9190536d7630e470af20e31059
|
File details
Details for the file ccfx-1.1.2-py3-none-any.whl.
File metadata
- Download URL: ccfx-1.1.2-py3-none-any.whl
- Upload date:
- Size: 43.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
420883c32e00acffb7d8c254ace77b1955840135250fb4a75794597a03ca1b90
|
|
| MD5 |
c7cd3108ef63575e5e8d5fe2b8f6ba67
|
|
| BLAKE2b-256 |
27b46d0c0849081bd34c148104facfdf6716612e5253b69fb8a3e0dd8c1c5ebd
|