Skip to content

Commit 72d3d00

Browse files
committed
publish
1 parent 48eb8c8 commit 72d3d00

14 files changed

+217
-15
lines changed

.github/workflows/publish.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Publish Python Package
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout repository
14+
uses: actions/checkout@v3
15+
16+
- name: Set up Python
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: '3.x'
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -r requirements.txt
25+
pip install pytest
26+
27+
- name: Run tests
28+
run: pytest tests/
29+
30+
publish:
31+
runs-on: ubuntu-latest
32+
needs: test # Run only if tests succeed
33+
34+
steps:
35+
- name: Checkout repository
36+
uses: actions/checkout@v3
37+
38+
- name: Set up Python
39+
uses: actions/setup-python@v4
40+
with:
41+
python-version: '3.x'
42+
43+
- name: Install dependencies
44+
run: |
45+
python -m pip install --upgrade pip
46+
pip install setuptools wheel twine
47+
48+
- name: Build package
49+
run: python setup.py sdist bdist_wheel
50+
51+
- name: Publish package to PyPI
52+
env:
53+
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
54+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
55+
run: |
56+
twine upload dist/*

predictit_markets.py

Lines changed: 0 additions & 15 deletions
This file was deleted.

predictit_markets/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# __init__.py
2+
3+
# You can import your main module here if needed
4+
from .predictit_markets import *
Binary file not shown.
Binary file not shown.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# predictit_markets.py
2+
3+
import pandas as pd
4+
import requests
5+
6+
def market_data(market, time=90, maxContracts=6):
7+
"""
8+
Fetch market data from PredictIt's API and return as a DataFrame.
9+
10+
Parameters:
11+
- market (int): The market ID to fetch data for.
12+
- time: The timespan for which data is fetched. Options: '24h', 7, 30, 90 (in days).
13+
- maxContracts (int): The maximum number of contracts to fetch.
14+
15+
Returns:
16+
- pd.DataFrame: DataFrame containing the market data or None if an error occurred.
17+
"""
18+
url = f'https://www.predictit.org/api/Public/GetMarketChartData/{market}'
19+
params = {
20+
'timespan': time,
21+
'maxContracts': maxContracts,
22+
'isTimespanInHours': 'false'
23+
}
24+
try:
25+
response = requests.get(url, params=params)
26+
response.raise_for_status() # Raises an HTTPError for bad responses
27+
28+
data = response.json()
29+
df = pd.DataFrame(data)
30+
return df
31+
32+
except requests.exceptions.HTTPError as e:
33+
print(f"HTTP Error: {e}")
34+
except requests.exceptions.RequestException as e:
35+
print(f"Request Error: {e}")
36+
except ValueError as e:
37+
print(f"Error decoding JSON: {e}")
38+
except Exception as e:
39+
print(f"Unexpected error: {e}")
40+
41+
return None
42+
43+
def market_name(market):
44+
# this may not be the best way to do it, but it worked pretty well for me
45+
df = pd.read_json('https://www.predictit.org/api/marketdata/markets/'+str(market))
46+
# sets the market to a string and returns it.
47+
text = str(df['name'][0])
48+
return text

setup.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from setuptools import setup, find_packages
2+
3+
setup(
4+
name="predictit_markets", # Package name
5+
version="0.1.0", # Initial version
6+
author="Your Name",
7+
author_email="your.email@example.com",
8+
description="A package for interacting with PredictIt markets",
9+
long_description=open('README.md').read(),
10+
long_description_content_type='text/markdown',
11+
url="https://github.com/tuttlepower/predictit_markets",
12+
packages=find_packages(),
13+
package_data={
14+
'predictit_markets': ['images/*.png'] # Include image files in the package
15+
},
16+
classifiers=[
17+
"Programming Language :: Python :: 3",
18+
"License :: OSI Approved :: MIT License",
19+
"Operating System :: OS Independent",
20+
],
21+
python_requires='>=3.6',
22+
install_requires=[
23+
'requests',
24+
'pandas', # Add any dependencies your package needs
25+
],
26+
)

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# tests/__init__.py
154 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# test_integration_predictit_markets.py
2+
3+
import unittest
4+
from predictit_markets import predictit_markets
5+
6+
class TestPredictItMarketsIntegration(unittest.TestCase):
7+
8+
def test_real_api_call(self):
9+
# This test will hit the real API
10+
df = predictit_markets.market_data(8089)
11+
self.assertTrue(len(df) > 0)
12+
13+
if __name__ == '__main__':
14+
unittest.main()

tests/test_predictit_markets.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# tests/test_predictit_markets.py
2+
3+
import unittest
4+
from unittest.mock import patch, Mock
5+
import requests
6+
from predictit_markets.predictit_markets import market_data
7+
8+
class TestPredictItMarkets(unittest.TestCase):
9+
10+
@patch('predictit_markets.predictit_markets.requests.get')
11+
def test_market_data_success(self, mock_get):
12+
# Simulate a successful API response
13+
mock_response = Mock()
14+
mock_response.status_code = 200
15+
mock_response.json.return_value = [
16+
{'marketId': 8089, 'contractId': 31414, 'contractName': 'Shapiro', 'date': '2024-07-26T00:00:00', 'dateString': '2024-07-26', 'openSharePrice': 0.26, 'highSharePrice': 0.34, 'lowSharePrice': 0.25, 'closeSharePrice': 0.31, 'tradeVolume': 160257, 'lineColor': '#0D8ECF'}
17+
# Add more sample data here if needed
18+
]
19+
mock_get.return_value = mock_response
20+
21+
# Test the market_data function
22+
df = market_data(8089)
23+
24+
# Assert the DataFrame is not None and contains the expected data
25+
self.assertIsNotNone(df)
26+
self.assertEqual(len(df), 1)
27+
self.assertEqual(df.iloc[0]['contractName'], 'Shapiro')
28+
29+
@patch('predictit_markets.predictit_markets.requests.get')
30+
def test_market_data_http_error(self, mock_get):
31+
# Simulate an HTTP error response
32+
mock_response = Mock()
33+
mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError("404 Client Error: Not Found")
34+
mock_get.return_value = mock_response
35+
36+
# Test the market_data function
37+
df = market_data(9999) # Assuming 9999 is a non-existent market ID
38+
39+
# Assert the DataFrame is None due to the error
40+
self.assertIsNone(df)
41+
42+
@patch('predictit_markets.predictit_markets.requests.get')
43+
def test_market_data_request_exception(self, mock_get):
44+
# Simulate a request exception
45+
mock_get.side_effect = requests.exceptions.RequestException("Network error")
46+
47+
# Test the market_data function
48+
df = market_data(8089)
49+
50+
# Assert the DataFrame is None due to the exception
51+
self.assertIsNone(df)
52+
53+
@patch('predictit_markets.predictit_markets.requests.get')
54+
def test_market_data_json_error(self, mock_get):
55+
# Simulate a JSON decoding error
56+
mock_response = Mock()
57+
mock_response.status_code = 200
58+
mock_response.json.side_effect = ValueError("No JSON object could be decoded")
59+
mock_get.return_value = mock_response
60+
61+
# Test the market_data function
62+
df = market_data(8089)
63+
64+
# Assert the DataFrame is None due to JSON error
65+
self.assertIsNone(df)
66+
67+
if __name__ == '__main__':
68+
unittest.main()

0 commit comments

Comments
 (0)