Skip to content

Commit 3e0f82a

Browse files
authored
Merge pull request #9 from derivexyz/fix/cicd
fix: poetry cicd
2 parents f6335e8 + 2b964d7 commit 3e0f82a

11 files changed

+795
-883
lines changed

.github/workflows/publish-to-pypi.yml

+20-36
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ on: push
44
jobs:
55
build:
66
name: Build distribution 📦
7+
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
78
runs-on: ubuntu-latest
9+
permissions:
10+
contents: write # IMPORTANT: mandatory for trusted publishing
811

912
steps:
1013
- uses: actions/checkout@v4
@@ -13,43 +16,24 @@ jobs:
1316
with:
1417
python-version: "3.9"
1518

16-
- name: Install project dependencies
17-
run: pip install -r requirements.txt
19+
- name: Install Poetry
20+
run: |
21+
curl -sSL https://install.python-poetry.org | python3 -
22+
echo "$HOME/.local/bin" >> $GITHUB_PATH
1823
19-
- name: Install pypa/build
20-
run: >-
21-
python3 -m
22-
pip install
23-
build
24-
--user
24+
- name: Configure Poetry
25+
run: |
26+
poetry config pypi-token.pypi $PYPI_TOKEN
27+
env:
28+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
2529

26-
- name: Build a binary wheel and a source tarball
27-
run: python3 -m build
30+
- name: Install project dependencies
31+
run: poetry install
2832

29-
- name: Store the distribution packages
30-
uses: actions/upload-artifact@v3
31-
with:
32-
name: python-package-distributions
33-
path: dist/
33+
- name: Publish to PyPI
34+
run: poetry build
35+
env:
36+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
3437

35-
publish-to-pypi:
36-
name: >-
37-
Publish Python 🐍 distribution 📦 to PyPI
38-
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
39-
needs:
40-
- build
41-
runs-on: ubuntu-latest
42-
environment:
43-
name: pypi
44-
url: https://pypi.org/p/derive_action_signing # Replace <package-name> with your PyPI project name
45-
permissions:
46-
id-token: write # IMPORTANT: mandatory for trusted publishing
47-
48-
steps:
49-
- name: Download all the dists
50-
uses: actions/download-artifact@v3
51-
with:
52-
name: python-package-distributions
53-
path: dist/
54-
- name: Publish distribution 📦 to PyPI
55-
uses: pypa/gh-action-pypi-publish@release/v1
38+
- name: Publish to PyPI
39+
run: poetry publish

.github/workflows/unit-test.yml

+7-13
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,15 @@ jobs:
1313
with:
1414
python-version: "3.9"
1515

16-
- name: Install pytest
17-
run: >-
18-
python3 -m
19-
pip install
20-
pytest requests
21-
--user
16+
- name: Install Poetry
17+
run: |
18+
curl -sSL https://install.python-poetry.org | python3 -
19+
echo "$HOME/.local/bin" >> $GITHUB_PATH
2220
23-
- name: Install project dependencies
24-
run: pip install -r requirements.txt
2521
26-
- name: Install current package
27-
run: pip install .
22+
- name: Install project dependencies
23+
run: poetry install
2824

29-
- name: Print installed packages
30-
run: pip list
3125

3226
- name: Unit-Test
33-
run: pytest -s
27+
run: poetry run pytest -s

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,7 @@ Thank you 8baller for building a full Python client for the v2 API. Much of the
6060

6161
## Developers
6262

63-
1. Create venv and run `pip install -e .`, this reflects changes in package immediately in venv
64-
2. Install dev related packages with `pip install -r requirements-dev.txt`
63+
1. Install Poetry: curl -sSL https://install.python-poetry.org | python3 -
64+
2. `poetry install`
65+
3. `poetry shell` (activate venv)
66+
4. `pytest`

poetry.lock

+690-738
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "derive_action_signing"
3-
version = "0.0.8"
3+
version = "0.0.9"
44
authors = [
55
"Derive.xyz <[email protected]>",
66
"8baller <[email protected]>"
@@ -15,8 +15,8 @@ classifiers = [
1515
]
1616

1717
[tool.poetry.urls]
18-
homepage = "https://github.com/derivexyz/v2-action-signing-python"
19-
repository = "https://github.com/derivexyz/v2-action-signing-python"
18+
Homepage = "https://github.com/derivexyz/v2-action-signing-python"
19+
Repository = "https://github.com/derivexyz/v2-action-signing-python"
2020

2121
[tool.poetry.dependencies]
2222
python = ">=3.9,<4.0"
@@ -25,6 +25,7 @@ web3 = ">=6.4.0,<7.0.0"
2525
hexbytes = ">=0.3.1"
2626
eth-account = ">=0.13.4"
2727
setuptools = "^75.8.0"
28+
eth-typing = "4.0.0"
2829

2930
[tool.poetry.group.dev.dependencies]
3031
pytest = ">=3.0"

requirements-dev.txt

-3
This file was deleted.

requirements.txt

-38
This file was deleted.

tests/conftest.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,17 @@ def live_instrument_ticker():
5151
"""
5252
Return all live ETH option tickers and extract sub_id.
5353
"""
54-
url = "https://api-demo.lyra.finance/public/get_instruments"
55-
payload = {
56-
"expired": False,
57-
"instrument_type": "option",
58-
"currency": "ETH",
59-
}
60-
response = requests.post(
61-
url, json=payload, headers={"accept": "application/json", "content-type": "application/json"}
62-
)
63-
64-
return response.json()["result"][0]
54+
return _get_live_instrument_ticker(nth=0)
6555

6656

6757
@pytest.fixture(scope="module")
6858
def second_live_instrument_ticker():
6959
"""
7060
Return all live ETH option tickers and extract sub_id.
7161
"""
62+
return _get_live_instrument_ticker(nth=1)
63+
64+
def _get_live_instrument_ticker(nth=0):
7265
url = "https://api-demo.lyra.finance/public/get_instruments"
7366
payload = {
7467
"expired": False,
@@ -79,4 +72,12 @@ def second_live_instrument_ticker():
7972
url, json=payload, headers={"accept": "application/json", "content-type": "application/json"}
8073
)
8174

82-
return response.json()["result"][1]
75+
# return the first is_active true instrument
76+
for instrument in response.json()["result"]:
77+
if instrument["is_active"]:
78+
nth -= 1
79+
80+
if nth == -1:
81+
return instrument
82+
83+
raise ValueError("No active instrument found")

tests/test_sign_order.py

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def test_sign_order(
7373
},
7474
)
7575

76+
print("test sign order response", response.json())
7677
results = response.json()["result"]
7778

7879
assert ("0x" + action._get_action_hash().hex()) == results["action_hash"]

tests/test_sign_rfq_execute.py

+28-19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,32 @@ def test_sign_rfq_execute(
2020
web3_client = Web3()
2121
session_key_wallet = web3_client.eth.account.from_key(SESSION_KEY_PRIVATE_KEY)
2222

23+
24+
########################
25+
# Create legs and sort #
26+
########################
27+
28+
legs = [
29+
RFQQuoteDetails(
30+
instrument_name=live_instrument_ticker["instrument_name"],
31+
direction="sell",
32+
asset_address=live_instrument_ticker["base_asset_address"],
33+
sub_id=int(live_instrument_ticker["base_asset_sub_id"]),
34+
price=Decimal("50"),
35+
amount=Decimal("1"),
36+
),
37+
RFQQuoteDetails(
38+
instrument_name=second_live_instrument_ticker["instrument_name"],
39+
direction="buy",
40+
asset_address=second_live_instrument_ticker["base_asset_address"],
41+
sub_id=int(second_live_instrument_ticker["base_asset_sub_id"]),
42+
price=Decimal("100"),
43+
amount=Decimal("2"),
44+
),
45+
]
46+
47+
sorted_legs = list(sorted(legs, key=lambda leg: leg.instrument_name))
48+
2349
#####################
2450
# Sign order action #
2551
#####################
@@ -36,24 +62,7 @@ def test_sign_rfq_execute(
3662
module_data=RFQExecuteModuleData(
3763
global_direction=global_direction,
3864
max_fee=Decimal("1000"),
39-
legs=[
40-
RFQQuoteDetails(
41-
instrument_name=live_instrument_ticker["instrument_name"],
42-
direction="sell",
43-
asset_address=live_instrument_ticker["base_asset_address"],
44-
sub_id=int(live_instrument_ticker["base_asset_sub_id"]),
45-
price=Decimal("50"),
46-
amount=Decimal("1"),
47-
),
48-
RFQQuoteDetails(
49-
instrument_name=second_live_instrument_ticker["instrument_name"],
50-
direction="buy",
51-
asset_address=second_live_instrument_ticker["base_asset_address"],
52-
sub_id=int(second_live_instrument_ticker["base_asset_sub_id"]),
53-
price=Decimal("100"),
54-
amount=Decimal("2"),
55-
),
56-
],
65+
legs=sorted_legs,
5766
),
5867
DOMAIN_SEPARATOR=domain_separator,
5968
ACTION_TYPEHASH=action_typehash,
@@ -80,7 +89,7 @@ def test_sign_rfq_execute(
8089
"content-type": "application/json",
8190
},
8291
)
83-
print("RESPONSE", response.json())
92+
print("test sign rfq quote execute response", response.json())
8493
results = response.json()["result"]
8594

8695
assert "0x" + action.module_data._encoded_legs().hex() == results["encoded_legs"]

tests/test_sign_rfq_quote.py

+28-19
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@ def test_sign_rfq_quote(
2020
web3_client = Web3()
2121
session_key_wallet = web3_client.eth.account.from_key(SESSION_KEY_PRIVATE_KEY)
2222

23+
########################
24+
# Create legs and sort #
25+
########################
26+
legs = [
27+
RFQQuoteDetails(
28+
instrument_name=live_instrument_ticker["instrument_name"],
29+
direction="buy",
30+
asset_address=live_instrument_ticker["base_asset_address"],
31+
sub_id=int(live_instrument_ticker["base_asset_sub_id"]),
32+
price=Decimal("50"),
33+
amount=Decimal("1"),
34+
),
35+
RFQQuoteDetails(
36+
instrument_name=second_live_instrument_ticker["instrument_name"],
37+
direction="buy",
38+
asset_address=second_live_instrument_ticker["base_asset_address"],
39+
sub_id=int(second_live_instrument_ticker["base_asset_sub_id"]),
40+
price=Decimal("100"),
41+
amount=Decimal("2"),
42+
),
43+
]
44+
sorted_legs = list(sorted(legs, key=lambda leg: leg.instrument_name))
45+
46+
2347
#####################
2448
# Sign order action #
2549
#####################
@@ -36,24 +60,7 @@ def test_sign_rfq_quote(
3660
module_data=RFQQuoteModuleData(
3761
global_direction=global_direction,
3862
max_fee=Decimal("1000"),
39-
legs=[
40-
RFQQuoteDetails(
41-
instrument_name=live_instrument_ticker["instrument_name"],
42-
direction="buy",
43-
asset_address=live_instrument_ticker["base_asset_address"],
44-
sub_id=int(live_instrument_ticker["base_asset_sub_id"]),
45-
price=Decimal("50"),
46-
amount=Decimal("1"),
47-
),
48-
RFQQuoteDetails(
49-
instrument_name=second_live_instrument_ticker["instrument_name"],
50-
direction="buy",
51-
asset_address=second_live_instrument_ticker["base_asset_address"],
52-
sub_id=int(second_live_instrument_ticker["base_asset_sub_id"]),
53-
price=Decimal("100"),
54-
amount=Decimal("2"),
55-
),
56-
],
63+
legs=sorted_legs,
5764
),
5865
DOMAIN_SEPARATOR=domain_separator,
5966
ACTION_TYPEHASH=action_typehash,
@@ -64,7 +71,7 @@ def test_sign_rfq_quote(
6471
assert action.signature is not None
6572

6673
############################
67-
# compare with debug route #
74+
# Compare with debug route #
6875
############################
6976

7077
response = requests.post(
@@ -80,6 +87,8 @@ def test_sign_rfq_quote(
8087
"content-type": "application/json",
8188
},
8289
)
90+
91+
print("test sign rfq quote response", response.json())
8392
results = response.json()["result"]
8493
assert "0x" + action.module_data.to_abi_encoded().hex() == results["encoded_data"]
8594
assert "0x" + action._get_action_hash().hex() == results["action_hash"]

0 commit comments

Comments
 (0)