Skip to main content

Python library Builder with CLI

Project description

pylibup

Personal and Opinionated Pylib Builder with CLI


Motivation

Since I've been on a recent building spree, I've been trying to adopt the DRY methodology. Mostly releasing smaller modules that aren't mono-repos. But copying and pasting templates got boring. So this sets to solve a few things that I use in particular, and likely won't be useful if your use case doesn't fit as well.

The end goal is that the structure should almost be pip install-able as is.

Tasks:

  • Setup a sane setup.py

  • Create some base module files in the correct structure

  • Adds .gitignores by default to prevent my default working files to be added

  • Creates CI/CD github workflows for:

    • Autopublish to Pypi

    • Docker Image releases (if part of an app)

  • Sets up repo secrets for dependent CI/CD workflows

Why should you use this over other ones such as cookie-cutter? I dont know, you probably shouldn't.


Quickstart

pip install --upgrade pylibup

Usage

cd ~/path/to/github
mkdir newlib && cd newlib

## This will generate a metadata.yaml in the cwd. You can then edit that file.

pylibup repo init

## Options & Args
# - name: Optional[str] = Argument(None) = name of python library
# - project_dir: Optional[str] = Argument(get_cwd()) = where the project should go
# - repo_user: Optional[str] = Argument(None) = your github username, or optionally, an org repo
# - github_token: Optional[str] = Option("", envvar="GITHUB_TOKEN") = auth token for github
# - private: bool = Option(True, "--public") = whether the repo should be published publicly, private by default.
# - overwrite: bool = Option(False) = overwrite existing files that were created
# - overwrite_state: bool = Option(False) = overwrite existing local state

## This will construct the library according to the metadata.yaml specs

pylibup repo build

## Options & Args
# config_file: Optional[str] = Argument(get_cwd('metadata.yaml')) = where your metadata.yaml should be located
# name: Optional[str] = Argument(None) 
# project_dir: Optional[str] = Argument(get_cwd()),
# github_token: Optional[str] = Option("", envvar="GITHUB_TOKEN"),
# pypirc_path: Optional[str] = Option("~/.pypirc", envvar="PYPIRC_PATH"),
# commit_msg: Optional[str] = Option("Initialize"),
# auto_publish: bool = Option(False), # If auto_publish == True, then will automatically push to github
# overwrite: bool = Option(False),
# overwrite_state: bool = Option(False),

## Used whenever you didnt specify auto_publish = True

pylibup repo publish

## Options & Args
# config_file: Optional[str] = Argument(get_cwd('metadata.yaml')),
# github_token: Optional[str] = Option("", envvar="GITHUB_TOKEN"), 
# pypirc_path: Optional[str] = Option("~/.pypirc", envvar="PYPIRC_PATH"),
# commit_msg: Optional[str] = Option("Initialize"),
# overwrite_state: bool = Option(False),

## Additionally you can utilize the build.sh script
sh build.sh dist # releases to main pypi
sh build.sh # will deploy to testpypi

Statefulness

CLI Apps tend to have bad statefulness. Two statefiles are created:

  • local: the current project folder

  • global: where the lib is installed

You can set certain configs like github_token to where it will always load, rather than having to set it each time.

The global state is loaded first, and overridden by local state values.

Note: if you reinstall this library, the global state will likely be erased.

pylibup state set github_token=ghp_xtyz anothervalue=1234

## Options and Args
# states: List[str] where a state is "x=y"
# --global-state: will write to global state versus local state
# --overwrite-state: will overwrite current values, true by default

"""
[pylib] app.set_state     Setting github_token -> ghp_xtyz. Previous: None
"""

Metadata Templating

Below is the base configuration for the metadata that is autogenerated

# These will automatically be added to .gitignore
gitignores:
- cache*
- '*.DS_Store'
- tests*
- __pycache__*
- '*logs'
- '*dist'
- '*build'
- '**build.sh'
- '*test.py'
- '*.egg-info*'
- '*.vscode'
- '**.ipynb'
- '**meta.yaml'
- '**metadata.yaml' # avoids adding this metadata file 
- '**state.yaml'
# Some optional configs
options:
  default_branch: main # sets to the default branch of the repo
  include_app: true # creates an app/ which is intended to use if containerizing
  include_buildscript: true # includes a build.sh, allowing you to quickly publish to pypi
  include_dockerfile: true # includes a Dockerfile [using fastapi]
  include_init: true # includes an __init__.py file in your module root that adds all the modules
  include_reqtext: true # includes a requirements.txt in the repo root
  private: true # sets the repo to public or private
project_description: '' # metadata used for description text
readme_text: '' #will be merged into the README.md
# optionally use annotation such as
# readme_text: |
#   ## My Readme
#   this is the readme 
repo: trisongz/pylibup # the full name of your repo 
secrets: # Optional secrets that will be automatically added to your repo.
  AWS_ACCESS_KEY_ID: # as this is a dict, the key AWS_ACCESS_KEY_ID will be set as the secret key
    from: AWS_ACCESS_KEY_ID_SVC_ACCOUNT # but `from` is the key that is used to get env value
  AWS_REGION: us-east-1 # as this is a string, it will use this value directly.
  AWS_SECRET_ACCESS_KEY: # as this is empty (null), will use the `key` to get the env value
  #  Additionally, you can set any other values following the same pattern as above.
  # if no value is found, then it will not attempt to set the value.
setup:
  author: null # will attempt to gather from github user profile
  cli_cmds: [] # cli cmds to be added where an item = `pylibup = pylibup.cli:baseCli`
  email: ts@growthengineai.com # will attempt to gather from github user profile
  git_repo: trisongz/pylibup 
  kwargs: {} # additional setup keyword dict values to add to main setup function
  lib_name: pylibup # if you intend for your `import x` to be different than the repo name
  pkg_name: pylibup # the intended repo name
  pkg_version: 0.0.0a # app version
  require_py3: true # forces a check prior to installation
  require_py3_version: 3.7 # no value = no check
  requirements: # individual library requirements
  - lazycls
  - pylogz
  - yourreq>1.5
structure: # will create these under yourapp/
  modules: # so in this example, the following are created
  - classes # yourapp/classes.py
  - client # yourapp/client.py
  - config # yourapp/config.py
  - utils # yourapp/utils.py
workflows: # automatically create github workflows
  docker_build: false # a quick docker-build.yaml targeting the Dockerfile when new pushes are made
  docker_build_options: # specific build options for docker-build.yaml
    # so the image handle will be img_repo/app_name
    app_name: '' # the image name you want to publish under
    docker_options: 
      img_repo: '' 
    ecr_options:
      img_repo: ''
    require_ecr: true # will create specific templating for ecr
  pypi_publish: true # will create a workflow for pypi publish on push of setup.py and releases. Will also attempt to set PYPI_API_TOKEN if pypi_path is found to enable automagic.

Libraries & Dependencies

  • typer: used for CLI

  • PyGithub: Used as Github API interface

  • GitPython: Used for git interface

  • Jinja2: Used for templating

  • pyyaml: Used for loading/saving statefiles

  • pylogz: Used for logging

  • requests: Used for calling the github API directly.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pylibup-0.0.3.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

pylibup-0.0.3-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file pylibup-0.0.3.tar.gz.

File metadata

  • Download URL: pylibup-0.0.3.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.0 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for pylibup-0.0.3.tar.gz
Algorithm Hash digest
SHA256 32f13fa0e881003ad192e831a284db2ac7d71484af3899bb25d98fa90b01ab25
MD5 89dc5547a82e70312747e79e248e967d
BLAKE2b-256 6349433985bf1eca6294f80e0afdce2778e65634a4df4e6e655caa7e96c27690

See more details on using hashes here.

File details

Details for the file pylibup-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: pylibup-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 20.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.0 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.9

File hashes

Hashes for pylibup-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 c29c4d6b6afea11b32a1b0c980c071102b9fa53d14ae51b58feee4677a314f7d
MD5 4b5daa809d23d8329331ee30189c8684
BLAKE2b-256 5e4d6a69d2f04449c8406cbbfd905ad40c54a2c1e16c583c8db04f7eb312821f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page