Skip to main content

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.

Metadata

Release files for pylibup 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pylibup 0.0.3
File Size Uploaded Provenance Actions
pylibup-0.0.3.tar.gz 20.2 kB Without provenance Details for pylibup-0.0.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pylibup 0.0.3
File Interpreter ABI Platform Actions
pylibup-0.0.3-py3-none-any.whl Python 3 none any Details for pylibup-0.0.3-py3-none-any.whl

Total release size: 40.6 kB

Release files / pylibup-0.0.3.tar.gz

Download URL pylibup-0.0.3.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
32f13fa0e881003ad192e831a284db2ac7d71484af3899bb25d98fa90b01ab25
BLAKE2b-256 checksum
How to use checksums
6349433985bf1eca6294f80e0afdce2778e65634a4df4e6e655caa7e96c27690
Upload date
Uploaded using Trusted Publishing?
What is 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

Release files / pylibup-0.0.3-py3-none-any.whl

Download URL pylibup-0.0.3-py3-none-any.whl
Size 20.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c29c4d6b6afea11b32a1b0c980c071102b9fa53d14ae51b58feee4677a314f7d
BLAKE2b-256 checksum
How to use checksums
5e4d6a69d2f04449c8406cbbfd905ad40c54a2c1e16c583c8db04f7eb312821f
Upload date
Uploaded using Trusted Publishing?
What is 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

Security for pylibup 0.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page