aexpy


Nameaexpy JSON
Version 0.4.2 PyPI version JSON
download
home_page
SummaryAexPy /eɪkspaɪ/ is Api EXplorer in PYthon for detecting API breaking changes in Python packages.
upload_time2024-03-12 16:20:56
maintainer
docs_urlNone
author
requires_python>=3.12
license
keywords api backward compatibility breaking change python
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ![AexPy](https://socialify.git.ci/StardustDL/aexpy/image?description=1&font=Bitter&forks=1&issues=1&language=1&owner=1&pulls=1&stargazers=1&theme=Light "AexPy")

[![CI](https://github.com/StardustDL/aexpy/actions/workflows/ci.yml/badge.svg)](https://github.com/StardustDL/aexpy/actions/workflows/ci.yml) [![](https://img.shields.io/github/license/StardustDL/aexpy.svg)](https://github.com/StardustDL/coxbuild/blob/master/LICENSE) [![](https://img.shields.io/pypi/v/aexpy)](https://pypi.org/project/aexpy/) [![Downloads](https://pepy.tech/badge/aexpy?style=flat)](https://pepy.tech/project/aexpy) [![](https://img.shields.io/docker/pulls/stardustdl/aexpy?style=flat)](https://hub.docker.com/r/stardustdl/aexpy)

[AexPy](https://github.com/StardustDL/aexpy) */eɪkspaɪ/* is **A**pi **EX**plorer in **PY**thon for detecting API breaking changes in Python packages.

Explore AexPy's [APIs](https://aexpy.netlify.app/projects/aexpy), and the [main](https://aexpy.netlify.app/view/?url=https://stardustdl.github.io/aexpy/main.json) branch on **AexPy** itself. AexPy also runs an [index project](https://github.com/StardustDL-Labs/aexpy-index) for some packages shown [here](https://aexpy.netlify.app/), trying to replace `pypi.org` to `aexpy.netlify.app` in the package PyPI URLs to explore their APIs.

> [!NOTE]
> AexPy is the prototype implementation of the conference paper "**AexPy: Detecting API Breaking Changes in Python Packages**" in Proceedings of the 33rd IEEE International Symposium on Software Reliability Engineering ([ISSRE 2022](https://issre2022.github.io/)), Charlotte, North Carolina, USA, October 31 - November 3, 2022.
> 
> If you use our approach or results in your work, please cite it according to [the citation file](https://github.com/StardustDL/aexpy/blob/main/CITATIONS.bib).
> 
> X. Du and J. Ma, "AexPy: Detecting API Breaking Changes in Python Packages," 2022 IEEE 33rd International Symposium on Software Reliability Engineering (ISSRE), 2022, pp. 470-481, doi: 10.1109/ISSRE55969.2022.00052.

https://user-images.githubusercontent.com/34736356/182772349-af0a5f20-d009-4daa-b4a9-593922ed66fe.mov

- **How AexPy works?** Approach Design & Evaluation are in [AexPy's conference paper](https://ieeexplore.ieee.org/abstract/document/9978982), see also [talk](https://www.bilibili.com/video/BV1tv4y1D75F/) & [slides](https://stardustdl.github.io/assets/pdfs/aexpy/aexpy-slides.pdf).
- **How we implement AexPy?** Source Code & Implemetation are in [AexPy's repository](https://github.com/StardustDL/aexpy), see also [design (zh-cn)](https://stardustdl.github.io/assets/pdfs/aexpy/aexpy-chinasoft.pdf).
- **How to use AexPy?** Detailed Document & Data are in [AexPy's documents](https://aexpy-docs.netlify.app/), see also [video](https://www.bilibili.com/video/BV1PG411F77m/) and [online AexPy](https://aexpy.netlify.app/).

```mermaid
graph LR;
    Package-->Version-1;
    Package-->Version-2;
    Version-1-->Preprocessing-1;
    Version-2-->Preprocessing-2;
    Preprocessing-1-->Extraction-1;
    Preprocessing-2-->Extraction-2;
    Extraction-1-->Difference;
    Extraction-2-->Difference;
    Difference-->Evaluation;
    Evaluation-->Breaking-Changes;
```

AexPy also provides a framework to process Python packages, extract APIs, and detect changes, which is designed for easily reusing and customizing. See the following "Advanced Tools" section and the source code for details.

## Quick Start

Take the package [generator-oj-problem](https://pypi.org/project/generator-oj-problem/) v0.0.1 and v0.0.2 as an example.

- Save API descriptions to `cache/api1.json` and `cache/api2.json`
- Output report to `report.txt`

```sh
# Install AexPy package and tool
pip install aexpy

# Extract APIs from v0.0.1
echo generator-oj-problem@0.0.1 | aexpy extract - api1.json -r

# Extract APIs from v0.0.1
echo generator-oj-problem@0.0.2 | aexpy extract - api2.json -r

# Diff APIs between two versions
aexpy diff api1.json api2.json changes.json
```

View results on [online AexPy](https://aexpy.netlify.app/).

- generator-oj-problem@0.0.1 [Distribution](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.1/) and [API](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1/)
- generator-oj-problem@0.0.2 [Distribution](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.2/) and [API](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/)
- [Changes](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1..0.0.2/) and [Report](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1&0.0.2/)

See also about [API Level](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=level), [Call Graph](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=callgraph), and [Inheritance Diagram](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=inheritance).

## Features

- Preprocessing
  - Download packages and get source code, or use existing code base.
  - Count package file sizes and lines of code.
  - Read package metadata and detect top modules.
- Extracting
  - Extract APIs from Python packages, including modules, classes, functions, attributes.
  - Collect detailed APIs, including parameters, instance attributes.
  - Detect API aliases and build call graphs, inheritance diagrams.
  - Enrich type information for APIs by static type analyzers.
- Diffing
  - Detect API changes after pairing APIs between two versions.
  - Grade changes by their severities.
- Reporting
  - Generate a human-readable report for API change detection results.
- Framework
  - Customize processors and implementation details.
  - Process Python packages in AexPy's general pipeline with logging and caching.
  - Generate portable data in JSON for API descriptions, changes, and so on.
  - Execute processing and view data by AexPy's command-line, with stdin/stdout supported.

## Install

We provide the Python package on PyPI. Use pip to install the package.

```sh
python -m pip install --upgrade aexpy
aexpy --help
```

> [!IMPORTANT]
> Please ensure your Python interpreter works in [UTF-8 mode](https://peps.python.org/pep-0540/).

We also provide the Docker image to avoid environment errors.

```sh
docker pull stardustdl/aexpy:latest
docker run --rm stardustdl/aexpy:latest --help

# or the image from the main branch
docker pull stardustdl/aexpy:main
```

## Usage

> [!TIP]
> - AexPy match commands by their prefixes, so you do not need to write the whole command name, but just a distinguishable prefix.
>   ```sh
>   # aexpy preprocess --help
>   aexpy pre --help
>   ```
> - All results produced by AexPy are in JSON format, so you could modify it in any text editor.
> - Pass `-` to I/O arguments to use stdin/stdout.


### Preprocess

Preprocess a distribution for a package release.

AexPy provide four preprocessing modes:

- `-s`, `--src`: (default) Use given distribution information (path to code, package name, modules)
- `-r`, `--release`: download and unpack the package wheel and automatically load from dist-info
- `-w`, `--wheel`: Unpack existing package wheel file and automatically load from dist-info
- `-d`, `--dist`: Automatically load from unpacked wheel, and its dist-info

AexPy will automatically load package name, version, top-level modules, and dependencies from dist-info.

There are also options to specify fields in the distribution:

- `-p`, `--project`: Package name and its version, e.g. `project@version`.
- `-m`, `--module`: (multiple) Top-level module names.
- `-D`, `--depends`: (multiple) Package dependencies.
- `-R`, `--requirements`: Package `requirements.txt` file path, to load dependencies.
- `-P`, `--pyversion`: Specify Python version for this distribution, supported Python 3.8+.

> [!TIP]
> You could modify the generated distribution file in a text editor to change field values.

```sh
# download the package wheel and unpack into ./cache
# output the distribution file to ./cache/distribution.json
aexpy preprocess -r -p generator-oj-problem@0.0.1 ./cache ./cache/distribution.json
# or output the distribution file to stdout
aexpy preprocess -r -p generator-oj-problem@0.0.1 ./cache -

# use existing wheel file
aexpy preprocess -w ./cache/generator_oj_problem-0.0.1-py3-none-any.whl ./cache/distribution.json

# use existing unpacked wheel directory, auto load metadata from .dist-info directory
aexpy preprocess -d ./cache/generator_oj_problem-0.0.1-py3-none-any ./cache/distribution.json

# use existing source code directory, given the package's name, version, and top-level modules
aexpy preprocess ./cache/generator_oj_problem-0.0.1-py3-none-any ./cache/distribution.json -p generator-oj-problem@0.0.1 -m generator_oj_problem
```

> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.1/).

### Extract

Extract the API description from a distribution.

AexPy provide four modes for the input distribution file:

- `-j`, `--json`: (default) The file is the JSON file produced by AexPy (`preprocess` command)
- `-r`, `--release`: The file is a text containing the release ID, e.g., `aexpy@0.1.0`
- `-w`, `--wheel`: The file is a wheel, i.e., `.whl` file. when reading from stdin, please also give the wheel file name through `--wheel-name` option.
- `-s`, `--src`: The file is a ZIP file that contains the package code directory
  - Please ensure the directory is at the root of the ZIP archive

> [!IMPORTANT]
> **About Dependencies**
> AexPy would dynamically import the target module to detect all available APIs. So please ensure all dependencies have been installed in the extraction environment, or specify the `dependencies` field in the distribution, and AexPy will install them into the extraction environment.
> 
> If the `wheelFile` field is valid (i.e. the target file exists), AexPy will firstly try to install the wheel and ignore the `dependencies` field (used when the wheel installation fails).

> [!TIP]
> **About Environment**
> AexPy use [micromamba](https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html) as default environment manager. Use `AEXPY_ENV_PROVIDER` environment variable to specify `conda`, `mamba`, or `micromamba` (if the variable hasn't been specified, AexPy will detect the environment manager automatically).
> 
> - Use flag `--no-temp` to let AexPy use the current Python environment (as same as AexPy) as the extraction environment (the default behavior of the installed AexPy package).
> - Use flag `--temp` to let AexPy create a temporary mamba(conda) environment that matches the distribution's pyverion field (the default behavior of our docker image).
> - Use option `-e`, `--env` to specify an existing mamba(conda) env name as the extraction environment (will ignore the temp flag).

```sh
aexpy extract ./cache/distribution.json ./cache/api.json
# or input the distribution file from stdin
# (this feature is also supported in other commands)
aexpy extract - ./cache/api.json
# or output the api description file to stdout
aexpy extract ./cache/distribution.json -

# extract from the target project release
echo aexpy@0.0.1 | aexpy extract - api.json -r
# extract from the wheel file
aexpy extract ./temp/aexpy-0.1.0.whl api.json -w
cat ./temp/aexpy-0.1.0.whl | aexpy extract - api.json -w --wheel-name aexpy-0.1.0.whl
# extract from the project source code ZIP archive
zip -r - ./project | aexpy extract - api.json -s

# Use a env named demo-env
aexpy extract ./cache/distribution.json - -e demo-env
# Create a temporary env
aexpy extract ./cache/distribution.json - --temp
```

> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1/).

### Diff

Diff two API descriptions and detect changes.

```sh
aexpy diff ./cache/api1.json ./cache/api2.json ./cache/diff.json
```

> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1..0.0.2/).

> [!TIP]
> If you have both stdin for OLD and NEW, please split two API descriptions by a comma `,`.
> 
> This situation only support for normal IO mode, not compressing IO mode.
> ```sh
> echo "," | cat ./api1.json - ./api2.json | aexpy diff - - ./changes.json
> ```

### Report

Generate report from detect changes.

```sh
aexpy report ./cache/diff.json ./cache/report.json
```

> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1&0.0.2/).

### View

View produced data.

```sh
aexpy view ./cache/distribution1.json
aexpy view ./cache/distribution2.json
aexpy view ./cache/api1.json
aexpy view ./cache/api2.json
aexpy view ./cache/diff.json
aexpy view ./cache/report.json
```

### Docker Image

The docker image keeps the same command-line interface, but always use stdin/stdout for host-container data transferring.

```sh
echo generator-oj-problem@0.0.1 | docker run -i aexpy/aexpy extract - - > ./api.json

echo "," | cat ./api1.json - ./api2.json | docker run -i aexpy/aexpy diff - - - > ./changes.json
```

> [!TIP]
> If you want to write processed data to filesystem, not the standard IO, add a volume mapping to `/data` for file access.
> 
> Since the container runs in non-root user, please use root user to allow the container writing to the mounted directory.
> 
> ```sh
> docker run -v $pwd/cache:/data -u root aexpy/aexpy extract /data/distribution.json /data/api.json
> ```

When you installed AexPy package, you could use `tool runimage` command for a quick runner of containers (if you have Docker installed).

```sh
# Use the same version of the image as current AexPy version
aexpy tool runimage ./mount -- --version
aexpy runimage ./mount -- --version

# Use a specified image tag
aexpy tool runimage ./mount -t stardustdl/aexpy:latest -- --version
```

## Advanced Tools

### Logging

The processing may cost time, you can use multiple `-v` for verbose logs (which are outputed to stderr).

```sh
aexpy -vvv view ./cache/report.json
```

### Compressed IO

When the package is large, the JSON data produced by AexPy might be large, too. AexPy support gzip format to compress/decompress for IO streams, use `-z/--gzip` option or `AEXPY_GZIP_IO` environemnt variable to enable it.

```sh
aexpy --gzip extract ./cache/distribution.json ./cache/api.json.gz
AEXPY_GZIP_IO=1 aexpy extract ./cache/distribution.json.gz ./cache/api.json
aexpy view ./cache/api.json.gz
```

> [!TIP]
> AexPy will detect input file format automatically, no matter compressed-IO enabled or not.
> 
> When enabling compressed-IO mode, all output JSON streams will be regarded as gzip JSON streams.

### Interactive

Add `-i` or `--interact` to enable interactive mode, every command will create an interactive Python shell after finishing processing. Here are some useful variable you could use in the interactive Python shell.

- `result`: The produced data object
- `context`: The producing context, use `exception` to access the exception if failing to process

```sh
aexpy -i view ./cache/report.json
```

> [!TIP]
> Feel free to use `locals()` and `dir()` to explore the interactive environment.

### Statistics

AexPy provides tools to count numbers from produced data in `aexpy.tools.stats` module.
It loads products from given files, runs builtin counters, and then records them as kay-value pairs of the release (or release pair).

```sh
aexpy tool stat ./*.json ./stats.json
aexpy stat ./*.json ./stats.json

aexpy view ./stats.json
```

### Pipeline

AexPy has four loosely-coupled stages in its pipeline. The adjacent stages transfer data by JSON, defined in [models](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/models/) directory. You can easily write your own implementation for every stage, and combine your implementation into the pipeline.

To write your own services, copy from [aexpy/services](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/services/__init__.py) and write your subclass of `ServiceProvider` and modify the `getService` function to return your service instance.

```python
from aexpy.services import ServiceProvider

class MyServiceProvider(ServiceProvider):
    ...

def getService():
    return MyServiceProvider()
```

Then you can load your service file by `-s/--service` option or `AEXPY_SERVICE` environment variable.

```sh
aexpy -s services.py -vvv view --help
AEXPY_SERVICE=services.py aexpy -vvv view --help
```

We have implemented an image service provider, which replaces the default extractor, differ, and reporter by the container worker. See [aexpy/services/workers.py](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/services/workers.py) for its implementation. Here is the demo service file to use the image service provider.

```python
from aexpy.services.workers import DockerWorkerServiceProvider

def getService():
    return DockerWorkerServiceProvider(tag="stardustdl/aexpy:latest")
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "aexpy",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": "",
    "keywords": "API,Backward Compatibility,Breaking Change,Python",
    "author": "",
    "author_email": "StardustDL <stardustdl@163.com>",
    "download_url": "https://files.pythonhosted.org/packages/bc/98/9565e3477a506d6addb40e172fc1d7f5e0d6d00124f6a72ef38f93e77f8e/aexpy-0.4.2.tar.gz",
    "platform": null,
    "description": "# ![AexPy](https://socialify.git.ci/StardustDL/aexpy/image?description=1&font=Bitter&forks=1&issues=1&language=1&owner=1&pulls=1&stargazers=1&theme=Light \"AexPy\")\n\n[![CI](https://github.com/StardustDL/aexpy/actions/workflows/ci.yml/badge.svg)](https://github.com/StardustDL/aexpy/actions/workflows/ci.yml) [![](https://img.shields.io/github/license/StardustDL/aexpy.svg)](https://github.com/StardustDL/coxbuild/blob/master/LICENSE) [![](https://img.shields.io/pypi/v/aexpy)](https://pypi.org/project/aexpy/) [![Downloads](https://pepy.tech/badge/aexpy?style=flat)](https://pepy.tech/project/aexpy) [![](https://img.shields.io/docker/pulls/stardustdl/aexpy?style=flat)](https://hub.docker.com/r/stardustdl/aexpy)\n\n[AexPy](https://github.com/StardustDL/aexpy) */e\u026akspa\u026a/* is **A**pi **EX**plorer in **PY**thon for detecting API breaking changes in Python packages.\n\nExplore AexPy's [APIs](https://aexpy.netlify.app/projects/aexpy), and the [main](https://aexpy.netlify.app/view/?url=https://stardustdl.github.io/aexpy/main.json) branch on **AexPy** itself. AexPy also runs an [index project](https://github.com/StardustDL-Labs/aexpy-index) for some packages shown [here](https://aexpy.netlify.app/), trying to replace `pypi.org` to `aexpy.netlify.app` in the package PyPI URLs to explore their APIs.\n\n> [!NOTE]\n> AexPy is the prototype implementation of the conference paper \"**AexPy: Detecting API Breaking Changes in Python Packages**\" in Proceedings of the 33rd IEEE International Symposium on Software Reliability Engineering ([ISSRE 2022](https://issre2022.github.io/)), Charlotte, North Carolina, USA, October 31 - November 3, 2022.\n> \n> If you use our approach or results in your work, please cite it according to [the citation file](https://github.com/StardustDL/aexpy/blob/main/CITATIONS.bib).\n> \n> X. Du and J. Ma, \"AexPy: Detecting API Breaking Changes in Python Packages,\" 2022 IEEE 33rd International Symposium on Software Reliability Engineering (ISSRE), 2022, pp. 470-481, doi: 10.1109/ISSRE55969.2022.00052.\n\nhttps://user-images.githubusercontent.com/34736356/182772349-af0a5f20-d009-4daa-b4a9-593922ed66fe.mov\n\n- **How AexPy works?** Approach Design & Evaluation are in [AexPy's conference paper](https://ieeexplore.ieee.org/abstract/document/9978982), see also [talk](https://www.bilibili.com/video/BV1tv4y1D75F/) & [slides](https://stardustdl.github.io/assets/pdfs/aexpy/aexpy-slides.pdf).\n- **How we implement AexPy?** Source Code & Implemetation are in [AexPy's repository](https://github.com/StardustDL/aexpy), see also [design (zh-cn)](https://stardustdl.github.io/assets/pdfs/aexpy/aexpy-chinasoft.pdf).\n- **How to use AexPy?** Detailed Document & Data are in [AexPy's documents](https://aexpy-docs.netlify.app/), see also [video](https://www.bilibili.com/video/BV1PG411F77m/) and [online AexPy](https://aexpy.netlify.app/).\n\n```mermaid\ngraph LR;\n    Package-->Version-1;\n    Package-->Version-2;\n    Version-1-->Preprocessing-1;\n    Version-2-->Preprocessing-2;\n    Preprocessing-1-->Extraction-1;\n    Preprocessing-2-->Extraction-2;\n    Extraction-1-->Difference;\n    Extraction-2-->Difference;\n    Difference-->Evaluation;\n    Evaluation-->Breaking-Changes;\n```\n\nAexPy also provides a framework to process Python packages, extract APIs, and detect changes, which is designed for easily reusing and customizing. See the following \"Advanced Tools\" section and the source code for details.\n\n## Quick Start\n\nTake the package [generator-oj-problem](https://pypi.org/project/generator-oj-problem/) v0.0.1 and v0.0.2 as an example.\n\n- Save API descriptions to `cache/api1.json` and `cache/api2.json`\n- Output report to `report.txt`\n\n```sh\n# Install AexPy package and tool\npip install aexpy\n\n# Extract APIs from v0.0.1\necho generator-oj-problem@0.0.1 | aexpy extract - api1.json -r\n\n# Extract APIs from v0.0.1\necho generator-oj-problem@0.0.2 | aexpy extract - api2.json -r\n\n# Diff APIs between two versions\naexpy diff api1.json api2.json changes.json\n```\n\nView results on [online AexPy](https://aexpy.netlify.app/).\n\n- generator-oj-problem@0.0.1 [Distribution](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.1/) and [API](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1/)\n- generator-oj-problem@0.0.2 [Distribution](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.2/) and [API](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/)\n- [Changes](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1..0.0.2/) and [Report](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1&0.0.2/)\n\nSee also about [API Level](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=level), [Call Graph](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=callgraph), and [Inheritance Diagram](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.2/?tab=inheritance).\n\n## Features\n\n- Preprocessing\n  - Download packages and get source code, or use existing code base.\n  - Count package file sizes and lines of code.\n  - Read package metadata and detect top modules.\n- Extracting\n  - Extract APIs from Python packages, including modules, classes, functions, attributes.\n  - Collect detailed APIs, including parameters, instance attributes.\n  - Detect API aliases and build call graphs, inheritance diagrams.\n  - Enrich type information for APIs by static type analyzers.\n- Diffing\n  - Detect API changes after pairing APIs between two versions.\n  - Grade changes by their severities.\n- Reporting\n  - Generate a human-readable report for API change detection results.\n- Framework\n  - Customize processors and implementation details.\n  - Process Python packages in AexPy's general pipeline with logging and caching.\n  - Generate portable data in JSON for API descriptions, changes, and so on.\n  - Execute processing and view data by AexPy's command-line, with stdin/stdout supported.\n\n## Install\n\nWe provide the Python package on PyPI. Use pip to install the package.\n\n```sh\npython -m pip install --upgrade aexpy\naexpy --help\n```\n\n> [!IMPORTANT]\n> Please ensure your Python interpreter works in [UTF-8 mode](https://peps.python.org/pep-0540/).\n\nWe also provide the Docker image to avoid environment errors.\n\n```sh\ndocker pull stardustdl/aexpy:latest\ndocker run --rm stardustdl/aexpy:latest --help\n\n# or the image from the main branch\ndocker pull stardustdl/aexpy:main\n```\n\n## Usage\n\n> [!TIP]\n> - AexPy match commands by their prefixes, so you do not need to write the whole command name, but just a distinguishable prefix.\n>   ```sh\n>   # aexpy preprocess --help\n>   aexpy pre --help\n>   ```\n> - All results produced by AexPy are in JSON format, so you could modify it in any text editor.\n> - Pass `-` to I/O arguments to use stdin/stdout.\n\n\n### Preprocess\n\nPreprocess a distribution for a package release.\n\nAexPy provide four preprocessing modes:\n\n- `-s`, `--src`: (default) Use given distribution information (path to code, package name, modules)\n- `-r`, `--release`: download and unpack the package wheel and automatically load from dist-info\n- `-w`, `--wheel`: Unpack existing package wheel file and automatically load from dist-info\n- `-d`, `--dist`: Automatically load from unpacked wheel, and its dist-info\n\nAexPy will automatically load package name, version, top-level modules, and dependencies from dist-info.\n\nThere are also options to specify fields in the distribution:\n\n- `-p`, `--project`: Package name and its version, e.g. `project@version`.\n- `-m`, `--module`: (multiple) Top-level module names.\n- `-D`, `--depends`: (multiple) Package dependencies.\n- `-R`, `--requirements`: Package `requirements.txt` file path, to load dependencies.\n- `-P`, `--pyversion`: Specify Python version for this distribution, supported Python 3.8+.\n\n> [!TIP]\n> You could modify the generated distribution file in a text editor to change field values.\n\n```sh\n# download the package wheel and unpack into ./cache\n# output the distribution file to ./cache/distribution.json\naexpy preprocess -r -p generator-oj-problem@0.0.1 ./cache ./cache/distribution.json\n# or output the distribution file to stdout\naexpy preprocess -r -p generator-oj-problem@0.0.1 ./cache -\n\n# use existing wheel file\naexpy preprocess -w ./cache/generator_oj_problem-0.0.1-py3-none-any.whl ./cache/distribution.json\n\n# use existing unpacked wheel directory, auto load metadata from .dist-info directory\naexpy preprocess -d ./cache/generator_oj_problem-0.0.1-py3-none-any ./cache/distribution.json\n\n# use existing source code directory, given the package's name, version, and top-level modules\naexpy preprocess ./cache/generator_oj_problem-0.0.1-py3-none-any ./cache/distribution.json -p generator-oj-problem@0.0.1 -m generator_oj_problem\n```\n\n> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/@0.0.1/).\n\n### Extract\n\nExtract the API description from a distribution.\n\nAexPy provide four modes for the input distribution file:\n\n- `-j`, `--json`: (default) The file is the JSON file produced by AexPy (`preprocess` command)\n- `-r`, `--release`: The file is a text containing the release ID, e.g., `aexpy@0.1.0`\n- `-w`, `--wheel`: The file is a wheel, i.e., `.whl` file. when reading from stdin, please also give the wheel file name through `--wheel-name` option.\n- `-s`, `--src`: The file is a ZIP file that contains the package code directory\n  - Please ensure the directory is at the root of the ZIP archive\n\n> [!IMPORTANT]\n> **About Dependencies**\n> AexPy would dynamically import the target module to detect all available APIs. So please ensure all dependencies have been installed in the extraction environment, or specify the `dependencies` field in the distribution, and AexPy will install them into the extraction environment.\n> \n> If the `wheelFile` field is valid (i.e. the target file exists), AexPy will firstly try to install the wheel and ignore the `dependencies` field (used when the wheel installation fails).\n\n> [!TIP]\n> **About Environment**\n> AexPy use [micromamba](https://mamba.readthedocs.io/en/latest/installation/micromamba-installation.html) as default environment manager. Use `AEXPY_ENV_PROVIDER` environment variable to specify `conda`, `mamba`, or `micromamba` (if the variable hasn't been specified, AexPy will detect the environment manager automatically).\n> \n> - Use flag `--no-temp` to let AexPy use the current Python environment (as same as AexPy) as the extraction environment (the default behavior of the installed AexPy package).\n> - Use flag `--temp` to let AexPy create a temporary mamba(conda) environment that matches the distribution's pyverion field (the default behavior of our docker image).\n> - Use option `-e`, `--env` to specify an existing mamba(conda) env name as the extraction environment (will ignore the temp flag).\n\n```sh\naexpy extract ./cache/distribution.json ./cache/api.json\n# or input the distribution file from stdin\n# (this feature is also supported in other commands)\naexpy extract - ./cache/api.json\n# or output the api description file to stdout\naexpy extract ./cache/distribution.json -\n\n# extract from the target project release\necho aexpy@0.0.1 | aexpy extract - api.json -r\n# extract from the wheel file\naexpy extract ./temp/aexpy-0.1.0.whl api.json -w\ncat ./temp/aexpy-0.1.0.whl | aexpy extract - api.json -w --wheel-name aexpy-0.1.0.whl\n# extract from the project source code ZIP archive\nzip -r - ./project | aexpy extract - api.json -s\n\n# Use a env named demo-env\naexpy extract ./cache/distribution.json - -e demo-env\n# Create a temporary env\naexpy extract ./cache/distribution.json - --temp\n```\n\n> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1/).\n\n### Diff\n\nDiff two API descriptions and detect changes.\n\n```sh\naexpy diff ./cache/api1.json ./cache/api2.json ./cache/diff.json\n```\n\n> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1..0.0.2/).\n\n> [!TIP]\n> If you have both stdin for OLD and NEW, please split two API descriptions by a comma `,`.\n> \n> This situation only support for normal IO mode, not compressing IO mode.\n> ```sh\n> echo \",\" | cat ./api1.json - ./api2.json | aexpy diff - - ./changes.json\n> ```\n\n### Report\n\nGenerate report from detect changes.\n\n```sh\naexpy report ./cache/diff.json ./cache/report.json\n```\n\n> View results at [AexPy Online](https://aexpy.netlify.app/projects/generator-oj-problem/0.0.1&0.0.2/).\n\n### View\n\nView produced data.\n\n```sh\naexpy view ./cache/distribution1.json\naexpy view ./cache/distribution2.json\naexpy view ./cache/api1.json\naexpy view ./cache/api2.json\naexpy view ./cache/diff.json\naexpy view ./cache/report.json\n```\n\n### Docker Image\n\nThe docker image keeps the same command-line interface, but always use stdin/stdout for host-container data transferring.\n\n```sh\necho generator-oj-problem@0.0.1 | docker run -i aexpy/aexpy extract - - > ./api.json\n\necho \",\" | cat ./api1.json - ./api2.json | docker run -i aexpy/aexpy diff - - - > ./changes.json\n```\n\n> [!TIP]\n> If you want to write processed data to filesystem, not the standard IO, add a volume mapping to `/data` for file access.\n> \n> Since the container runs in non-root user, please use root user to allow the container writing to the mounted directory.\n> \n> ```sh\n> docker run -v $pwd/cache:/data -u root aexpy/aexpy extract /data/distribution.json /data/api.json\n> ```\n\nWhen you installed AexPy package, you could use `tool runimage` command for a quick runner of containers (if you have Docker installed).\n\n```sh\n# Use the same version of the image as current AexPy version\naexpy tool runimage ./mount -- --version\naexpy runimage ./mount -- --version\n\n# Use a specified image tag\naexpy tool runimage ./mount -t stardustdl/aexpy:latest -- --version\n```\n\n## Advanced Tools\n\n### Logging\n\nThe processing may cost time, you can use multiple `-v` for verbose logs (which are outputed to stderr).\n\n```sh\naexpy -vvv view ./cache/report.json\n```\n\n### Compressed IO\n\nWhen the package is large, the JSON data produced by AexPy might be large, too. AexPy support gzip format to compress/decompress for IO streams, use `-z/--gzip` option or `AEXPY_GZIP_IO` environemnt variable to enable it.\n\n```sh\naexpy --gzip extract ./cache/distribution.json ./cache/api.json.gz\nAEXPY_GZIP_IO=1 aexpy extract ./cache/distribution.json.gz ./cache/api.json\naexpy view ./cache/api.json.gz\n```\n\n> [!TIP]\n> AexPy will detect input file format automatically, no matter compressed-IO enabled or not.\n> \n> When enabling compressed-IO mode, all output JSON streams will be regarded as gzip JSON streams.\n\n### Interactive\n\nAdd `-i` or `--interact` to enable interactive mode, every command will create an interactive Python shell after finishing processing. Here are some useful variable you could use in the interactive Python shell.\n\n- `result`: The produced data object\n- `context`: The producing context, use `exception` to access the exception if failing to process\n\n```sh\naexpy -i view ./cache/report.json\n```\n\n> [!TIP]\n> Feel free to use `locals()` and `dir()` to explore the interactive environment.\n\n### Statistics\n\nAexPy provides tools to count numbers from produced data in `aexpy.tools.stats` module.\nIt loads products from given files, runs builtin counters, and then records them as kay-value pairs of the release (or release pair).\n\n```sh\naexpy tool stat ./*.json ./stats.json\naexpy stat ./*.json ./stats.json\n\naexpy view ./stats.json\n```\n\n### Pipeline\n\nAexPy has four loosely-coupled stages in its pipeline. The adjacent stages transfer data by JSON, defined in [models](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/models/) directory. You can easily write your own implementation for every stage, and combine your implementation into the pipeline.\n\nTo write your own services, copy from [aexpy/services](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/services/__init__.py) and write your subclass of `ServiceProvider` and modify the `getService` function to return your service instance.\n\n```python\nfrom aexpy.services import ServiceProvider\n\nclass MyServiceProvider(ServiceProvider):\n    ...\n\ndef getService():\n    return MyServiceProvider()\n```\n\nThen you can load your service file by `-s/--service` option or `AEXPY_SERVICE` environment variable.\n\n```sh\naexpy -s services.py -vvv view --help\nAEXPY_SERVICE=services.py aexpy -vvv view --help\n```\n\nWe have implemented an image service provider, which replaces the default extractor, differ, and reporter by the container worker. See [aexpy/services/workers.py](https://github.com/StardustDL/aexpy/blob/main/src/aexpy/services/workers.py) for its implementation. Here is the demo service file to use the image service provider.\n\n```python\nfrom aexpy.services.workers import DockerWorkerServiceProvider\n\ndef getService():\n    return DockerWorkerServiceProvider(tag=\"stardustdl/aexpy:latest\")\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "AexPy /e\u026akspa\u026a/ is Api EXplorer in PYthon for detecting API breaking changes in Python packages.",
    "version": "0.4.2",
    "project_urls": {
        "Changelog": "https://github.com/StardustDL/aexpy/releases",
        "Documentation": "https://aexpy-docs.netlify.app/",
        "Homepage": "https://aexpy.netlify.app/",
        "Issues": "https://github.com/StardustDL/aexpy/issues",
        "Repository": "https://github.com/StardustDL/aexpy"
    },
    "split_keywords": [
        "api",
        "backward compatibility",
        "breaking change",
        "python"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "70f822a96ef31cf406d72a5c48db01e37547cc0e332ba93e9a49a5c269ec7c08",
                "md5": "098225959c31f79d11e7f6097a377872",
                "sha256": "857a741d77b24402cf4322aacbd7a47e8c872f12ccb452a43d2996b6ad601d03"
            },
            "downloads": -1,
            "filename": "aexpy-0.4.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "098225959c31f79d11e7f6097a377872",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 96444,
            "upload_time": "2024-03-12T16:20:48",
            "upload_time_iso_8601": "2024-03-12T16:20:48.931471Z",
            "url": "https://files.pythonhosted.org/packages/70/f8/22a96ef31cf406d72a5c48db01e37547cc0e332ba93e9a49a5c269ec7c08/aexpy-0.4.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bc989565e3477a506d6addb40e172fc1d7f5e0d6d00124f6a72ef38f93e77f8e",
                "md5": "8f7aa7e5562e3b2b27bdea90ef58b376",
                "sha256": "f4a82111255dd1d7128bc863a0176f156116cdd712a1eeedf5aeeebaab11fc50"
            },
            "downloads": -1,
            "filename": "aexpy-0.4.2.tar.gz",
            "has_sig": false,
            "md5_digest": "8f7aa7e5562e3b2b27bdea90ef58b376",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 233809,
            "upload_time": "2024-03-12T16:20:56",
            "upload_time_iso_8601": "2024-03-12T16:20:56.908502Z",
            "url": "https://files.pythonhosted.org/packages/bc/98/9565e3477a506d6addb40e172fc1d7f5e0d6d00124f6a72ef38f93e77f8e/aexpy-0.4.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-12 16:20:56",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "StardustDL",
    "github_project": "aexpy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "aexpy"
}
        
Elapsed time: 0.98954s