F. Eugene Aumson 0564ac1530
Python doc polish (#1757)
* Exercise doctests as a test not as a linter

* Add a contract artifact doctest, and exercise it

* Clean up linter issues

* Change asset data decoding output type

Previously, it was a TypedDict, but that was causing problems.  Sphinx
seems to be broken, such that none of the fields of the class were being
rendered into the doc.

Thinking on it further, I decided that a NamedTuple makes more sense
here anyways, since tuples are immutable and this output value isn't
something someone should ever build or modify.  And, NamedTuple is
getting its fields properly rendered by Sphinx.

* Add type annotations to JSON schemas docs

* Add doc publish metadata file for middlewares pkg

* Improve documentation

Note that none of the changes to .py files impact functionality in any
way, because the changes are restricted to "docstrings", which to the
Python interpreter are simply no-op statements.

However, one caveat to that is that much of these docstring changes DO
affect the functionality of automated test runs, because all of the code
examples (blocks beginning with `>>> `) are "doctests", which are
exercised via the test framework.

The index.rst files are the top-level templates for generating the
documentation, and the "automodule"/"autoclass"/etc statements pull in
the docstrings from the source code.

* correct package name in doc URL

* Move sra_client module into zero_ex namespace

* Add functions to encode asset data to bytes

* Fix: SRA client was deserializing orders weirdly

The generated code was transforming the order structure, from the camel
case field name format in the spec, into the snake case field name
format expected by Python convention.  With this problem in place, the
only way to take an order from a relayer and send it to a contract (for
fill, cancel, etc) was to manually transform the field names, one by
one, into a new structure.

* Fix problem with Web3/JSON order conversion utils

* doctest: maker, trade ZRX for WETH, not vice versa

* Remove redundant test

* Construct order in native Python, not JSON

Then convert it to JSON before sending it to the relayer.

* doctest: simplify asset units

* Add doctests for filling and cancelling

* Minor doctetst copy edits; whitespace

* Rename function, and add optional parameter

* Tweak docstrings on JSON conversion functions.

* Demo asset data decoding to view asset pairs

* Demo selecting an order from the order book

And have taker take it.

* Rename variable

* Abstract ganache from examples

Doing that exposed excessive use of the verbose
NETWORK_TO_ADDRESSES[NetworkId.Ganache] construct, so simplified that,
which ripped into eliminating other temporary variables that had been
used to hold specific contract addresses.

Also cleaned up some misplaced import statements.

* Add missing SRA client doc publication metadata

* Ran prettier on new SRA client doc pub metadata

* Remove local env customizations in doc metadata

* Eliminate temporary variable

* Rename variable

* Show `pip install` in every package's doc

* Doc NetorkID & pagination params as int, not float

* Clean up unmatched parenthesis in docs
2019-04-30 07:44:51 -04:00

196 lines
5.7 KiB
Python
Executable File

#!/usr/bin/env python
# coding: utf-8
"""setuptools module for sra_client package."""
import subprocess # nosec
import distutils.command.build_py
from urllib.request import urlopen
from urllib.error import URLError
from setuptools import setup, find_packages # noqa: H301
from setuptools.command.test import test as TestCommand
NAME = "0x-sra-client"
VERSION = "1.0.1"
# To install the library, run the following
#
# python setup.py install
#
# prerequisite: setuptools
# http://pypi.python.org/pypi/setuptools
with open("README.md", "r") as file_handle:
README_MD = file_handle.read()
REQUIRES = ["urllib3 >= 1.15", "six >= 1.10", "certifi", "python-dateutil"]
class TestCommandExtension(TestCommand):
"""Run pytest tests."""
def run_tests(self):
"""Invoke pytest."""
import pytest
exit(pytest.main(["--doctest-modules"]))
class TestPublishCommand(distutils.command.build_py.build_py):
"""Custom command to publish to test.pypi.org."""
description = (
"Publish dist/* to test.pypi.org. Run sdist & bdist_wheel first."
)
def run(self):
"""Run twine to upload to test.pypi.org."""
subprocess.check_call( # nosec
(
"twine upload --repository-url https://test.pypi.org/legacy/"
+ " --verbose dist/*"
).split()
)
class StartTestRelayerCommand(distutils.command.build_py.build_py):
"""Custom command to boot up a local 0x-launch-kit in docker."""
description = "Run launch-kit daemon to support tests."
def run(self):
"""Run `docker-compose up`."""
subprocess.call( # nosec
("docker-compose -f test/relayer/docker-compose.yml up -d").split()
)
launch_kit_ready = False
print("Waiting for relayer to start accepting connections...", end="")
while not launch_kit_ready:
try:
launch_kit_ready = (
urlopen( # nosec
"http://localhost:3000/v2/asset_pairs"
).getcode()
== 200
)
except URLError:
continue
print("done")
class StopTestRelayerCommand(distutils.command.build_py.build_py):
"""Custom command to tear down the local 0x-launch-kit test relayer."""
description = "Tear down launch-kit daemon."
def run(self):
"""Run `docker-compose down`."""
subprocess.call( # nosec
("docker-compose -f test/relayer/docker-compose.yml down").split()
)
class LintCommand(distutils.command.build_py.build_py):
"""Custom setuptools command class for running linters."""
description = "Run linters"
def run(self):
"""Run linter shell commands."""
lint_targets = "test src/zero_ex/sra_client/__init__.py setup.py"
lint_commands = [
# formatter:
(
f"black --line-length 79 --check --diff test {lint_targets}"
).split(),
# style guide checker (formerly pep8):
f"pycodestyle {lint_targets}".split(),
# docstring style checker:
f"pydocstyle {lint_targets}".split(),
# static type checker:
f"bandit -r {lint_targets}".split(),
# general linter:
f"pylint {lint_targets}".split(),
# pylint takes relatively long to run, so it runs last, to enable
# fast failures.
]
for lint_command in lint_commands:
print(
"Running lint command `", " ".join(lint_command).strip(), "`"
)
subprocess.check_call(lint_command) # nosec
class PublishCommand(distutils.command.build_py.build_py):
"""Custom command to publish to pypi.org."""
description = "Publish dist/* to pypi.org. Run sdist & bdist_wheel first."
def run(self):
"""Run twine to upload to pypi.org."""
subprocess.check_call("twine upload dist/*".split()) # nosec
class PublishDocsCommand(distutils.command.build_py.build_py):
"""Custom command to publish docs to S3."""
description = (
"Publish docs to "
+ "http://0x-sra-client-py.s3-website-us-east-1.amazonaws.com/"
)
def run(self):
"""Run npm package `discharge` to build & upload docs."""
subprocess.check_call("discharge deploy".split()) # nosec
setup(
name=NAME,
version=VERSION,
description="Standard Relayer REST API",
author_email="",
url="https://github.com/0xproject/0x-monorepo/python-packages/sra_client",
keywords=["OpenAPI", "OpenAPI-Generator", "Standard Relayer REST API"],
install_requires=REQUIRES,
namespace_packages=["zero_ex"],
packages=find_packages("src"),
package_dir={"": "src"},
include_package_data=True,
long_description=README_MD,
long_description_content_type="text/markdown",
cmdclass={
"test_publish": TestPublishCommand,
"publish": PublishCommand,
"start_test_relayer": StartTestRelayerCommand,
"stop_test_relayer": StopTestRelayerCommand,
"lint": LintCommand,
"publish_docs": PublishDocsCommand,
"test": TestCommandExtension,
},
extras_require={
"dev": [
"0x-contract-artifacts",
"0x-contract-addresses",
"0x-order-utils",
"0x-web3",
"bandit",
"black",
"coverage",
"coveralls",
"pycodestyle",
"pydocstyle",
"pylint",
"pytest",
"sphinx",
"sphinx-autodoc-typehints",
]
},
command_options={
"build_sphinx": {
"source_dir": ("setup.py", "src"),
"build_dir": ("setup.py", "build/docs"),
}
},
)