Skip to content

Commit 6b986b4

Browse files
committed
feat: implement automated multi-language API documentation generation
1 parent 21b0ed5 commit 6b986b4

File tree

8 files changed

+1934
-4
lines changed

8 files changed

+1934
-4
lines changed

core/api-doc-config.json

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"methods": {
3+
"fetchMarkets": {
4+
"python": {
5+
"example": "markets = poly.fetch_markets(pmxt.MarketFilterParams(\n limit=20,\n sort='volume' # 'volume' | 'liquidity' | 'newest'\n))"
6+
},
7+
"typescript": {
8+
"example": "const markets = await polymarket.fetchMarkets({ \n limit: 20, \n offset: 0,\n sort: 'volume' // 'volume' | 'liquidity' | 'newest'\n});"
9+
}
10+
},
11+
"searchMarkets": {
12+
"python": {
13+
"example": "results = kalshi.search_markets('Fed rates', pmxt.MarketFilterParams(\n limit=10,\n search_in='title' # 'title' (default) | 'description' | 'both'\n))"
14+
},
15+
"typescript": {
16+
"example": "const results = await kalshi.searchMarkets('Fed rates', { \n limit: 10,\n searchIn: 'title' // 'title' (default) | 'description' | 'both'\n});"
17+
}
18+
},
19+
"getMarketsBySlug": {
20+
"python": {
21+
"example": "# Polymarket: use URL slug\npoly_markets = poly.get_markets_by_slug('who-will-trump-nominate-as-fed-chair')\n\n# Kalshi: use market ticker (auto-uppercased)\nkalshi_markets = kalshi.get_markets_by_slug('KXFEDCHAIRNOM-29')"
22+
},
23+
"typescript": {
24+
"example": "// Polymarket: use URL slug\nconst polyMarkets = await polymarket.getMarketsBySlug('who-will-trump-nominate-as-fed-chair');\n\n// Kalshi: use market ticker (auto-uppercased)\nconst kalshiMarkets = await kalshi.getMarketsBySlug('KXFEDCHAIRNOM-29');"
25+
}
26+
},
27+
"fetchOHLCV": {
28+
"python": {
29+
"example": "markets = poly.search_markets('Trump')\noutcome_id = markets[0].outcomes[0].id # Get the outcome ID\n\ncandles = poly.fetch_ohlcv(outcome_id, pmxt.HistoryFilterParams(\n resolution='1h', # '1m' | '5m' | '15m' | '1h' | '6h' | '1d'\n start=datetime(2024, 1, 1),\n end=datetime(2024, 1, 31),\n limit=100\n))"
30+
},
31+
"typescript": {
32+
"example": "const markets = await polymarket.searchMarkets('Trump');\nconst outcomeId = markets[0].outcomes[0].id; // Get the outcome ID\n\nconst candles = await polymarket.fetchOHLCV(outcomeId, {\n resolution: '1h', // '1m' | '5m' | '15m' | '1h' | '6h' | '1d'\n start: new Date('2024-01-01'),\n end: new Date('2024-01-31'),\n limit: 100\n});"
33+
},
34+
"notes": [
35+
"**CRITICAL**: Use `outcome.id`, not `market.id`.",
36+
"- **Polymarket**: `outcome.id` is the CLOB Token ID",
37+
"- **Kalshi**: `outcome.id` is the Market Ticker"
38+
]
39+
},
40+
"fetchOrderBook": {
41+
"python": {
42+
"example": "order_book = kalshi.fetch_order_book('FED-25JAN')\nprint(f'Best bid: {order_book.bids[0].price}')\nprint(f'Best ask: {order_book.asks[0].price}')"
43+
},
44+
"typescript": {
45+
"example": "const orderBook = await kalshi.fetchOrderBook('FED-25JAN');\nconsole.log('Best bid:', orderBook.bids[0].price);\nconsole.log('Best ask:', orderBook.asks[0].price);"
46+
}
47+
},
48+
"fetchTrades": {
49+
"python": {
50+
"example": "trades = kalshi.fetch_trades('FED-25JAN', pmxt.HistoryFilterParams(\n resolution='1h',\n limit=100\n))"
51+
},
52+
"typescript": {
53+
"example": "const trades = await kalshi.fetchTrades('FED-25JAN', {\n resolution: '1h',\n limit: 100\n});"
54+
},
55+
"notes": [
56+
"**Note**: Polymarket requires API key. Use `fetchOHLCV` for public historical data."
57+
]
58+
},
59+
"fetchBalance": {
60+
"python": {
61+
"example": "balances = poly.fetch_balance()\nprint(balances)\n# [Balance(currency='USDC', total=1000, available=950, locked=50)]"
62+
},
63+
"typescript": {
64+
"example": "const balances = await polymarket.fetchBalance();\nconsole.log(balances);\n// [{ currency: 'USDC', total: 1000, available: 950, locked: 50 }]"
65+
}
66+
},
67+
"fetchPositions": {
68+
"python": {
69+
"example": "positions = kalshi.fetch_positions()\nfor pos in positions:\n print(f\"{pos.outcome_label}: {pos.size} @ ${pos.entry_price}\")\n print(f\"Unrealized P&L: ${pos.unrealized_pnl}\")"
70+
},
71+
"typescript": {
72+
"example": "const positions = await kalshi.fetchPositions();\npositions.forEach(pos => {\n console.log(`${pos.outcomeLabel}: ${pos.size} @ $${pos.entryPrice}`);\n console.log(`Unrealized P&L: $${pos.unrealizedPnL}`);\n});"
73+
}
74+
},
75+
"createOrder": {
76+
"python": {
77+
"example": "# Limit Order Example\norder = poly.create_order(pmxt.CreateOrderParams(\n market_id='663583',\n outcome_id='109918492287...',\n side='buy',\n type='limit',\n amount=10, # Number of contracts\n price=0.55 # Required for limit orders (0.0-1.0)\n))\n\nprint(f'Order {order.id}: {order.status}')\n\n# Market Order Example\norder = kalshi.create_order(pmxt.CreateOrderParams(\n market_id='FED-25JAN',\n outcome_id='FED-25JAN-YES',\n side='sell',\n type='market',\n amount=5 # Price not needed for market orders\n))"
78+
},
79+
"typescript": {
80+
"example": "// Limit Order Example\nconst order = await polymarket.createOrder({\n marketId: '663583',\n outcomeId: '10991849228756847439673778874175365458450913336396982752046655649803657501964',\n side: 'buy',\n type: 'limit',\n amount: 10, // Number of contracts\n price: 0.55 // Required for limit orders (0.0-1.0)\n});\n\nconsole.log(`Order ${order.id}: ${order.status}`);\n\n// Market Order Example\nconst order = await kalshi.createOrder({\n marketId: 'FED-25JAN',\n outcomeId: 'FED-25JAN-YES',\n side: 'sell',\n type: 'market',\n amount: 5 // Price not needed for market orders\n});"
81+
}
82+
},
83+
"cancelOrder": {
84+
"python": {
85+
"example": "cancelled_order = poly.cancel_order('order-123')\nprint(cancelled_order.status) # 'cancelled'"
86+
},
87+
"typescript": {
88+
"example": "const cancelledOrder = await polymarket.cancelOrder('order-123');\nconsole.log(cancelledOrder.status); // 'cancelled'"
89+
}
90+
},
91+
"fetchOrder": {
92+
"python": {
93+
"example": "order = kalshi.fetch_order('order-456')\nprint(f'Filled: {order.filled}/{order.amount}')"
94+
},
95+
"typescript": {
96+
"example": "const order = await kalshi.fetchOrder('order-456');\nconsole.log(`Filled: ${order.filled}/${order.amount}`);"
97+
}
98+
},
99+
"fetchOpenOrders": {
100+
"python": {
101+
"example": "# All open orders\nall_orders = poly.fetch_open_orders()\n\n# Open orders for specific market\nmarket_orders = kalshi.fetch_open_orders('FED-25JAN')\n\nfor order in all_orders:\n print(f'{order.side} {order.amount} @ {order.price}')"
102+
},
103+
"typescript": {
104+
"example": "// All open orders\nconst allOrders = await polymarket.fetchOpenOrders();\n\n// Open orders for specific market\nconst marketOrders = await kalshi.fetchOpenOrders('FED-25JAN');\n\nallOrders.forEach(order => {\n console.log(`${order.side} ${order.amount} @ ${order.price}`);\n});"
105+
}
106+
}
107+
},
108+
"workflowExample": {
109+
"python": "import pmxt\nimport os\n\nexchange = pmxt.Polymarket(\n private_key=os.getenv('POLYMARKET_PRIVATE_KEY')\n)\n\n# 1. Check balance\nbalances = exchange.fetch_balance()\nif balances:\n balance = balances[0]\n print(f'Available: ${balance.available}')\n\n# 2. Search for a market\nmarkets = exchange.search_markets('Trump')\nmarket = markets[0]\noutcome = market.outcomes[0]\n\n# 3. Place a limit order\norder = exchange.create_order(pmxt.CreateOrderParams(\n market_id=market.id,\n outcome_id=outcome.id,\n side='buy',\n type='limit',\n amount=10,\n price=0.50\n))\n\nprint(f'Order placed: {order.id}')\n\n# 4. Check order status\nupdated_order = exchange.fetch_order(order.id)\nprint(f'Status: {updated_order.status}')\nprint(f'Filled: {updated_order.filled}/{updated_order.amount}')\n\n# 5. Cancel if needed\nif updated_order.status == 'open':\n exchange.cancel_order(order.id)\n print('Order cancelled')\n\n# 6. Check positions\npositions = exchange.fetch_positions()\nfor pos in positions:\n pnl_sign = '+' if pos.unrealized_pnl > 0 else ''\n print(f'{pos.outcome_label}: {pnl_sign}${pos.unrealized_pnl:.2f}')",
110+
"typescript": "import pmxt from 'pmxtjs';\n\nconst exchange = new pmxt.Polymarket({\n privateKey: process.env.POLYMARKET_PRIVATE_KEY\n});\n\n// 1. Check balance\nconst [balance] = await exchange.fetchBalance();\nconsole.log(`Available: $${balance.available}`);\n\n// 2. Search for a market\nconst markets = await exchange.searchMarkets('Trump');\nconst market = markets[0];\nconst outcome = market.outcomes[0];\n\n// 3. Place a limit order\nconst order = await exchange.createOrder({\n marketId: market.id,\n outcomeId: outcome.id,\n side: 'buy',\n type: 'limit',\n amount: 10,\n price: 0.50\n});\n\nconsole.log(`Order placed: ${order.id}`);\n\n// 4. Check order status\nconst updatedOrder = await exchange.fetchOrder(order.id);\nconsole.log(`Status: ${updatedOrder.status}`);\nconsole.log(`Filled: ${updatedOrder.filled}/${updatedOrder.amount}`);\n\n// 5. Cancel if needed\nif (updatedOrder.status === 'open') {\n await exchange.cancelOrder(order.id);\n console.log('Order cancelled');\n}\n\n// 6. Check positions\nconst positions = await exchange.fetchPositions();\npositions.forEach(pos => {\n console.log(`${pos.outcomeLabel}: ${pos.unrealizedPnL > 0 ? '+' : ''}$${pos.unrealizedPnL.toFixed(2)}`);\n});"
111+
}
112+
}

core/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
"server:prod": "node dist/server/index.js",
2727
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=0.5.0,library=urllib3",
2828
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=0.5.0,supportsES6=true,typescriptThreePlus=true",
29-
"generate:sdk:all": "npm run generate:sdk:python && npm run generate:sdk:typescript"
29+
"generate:docs": "node ../scripts/generate-api-docs.js",
30+
"generate:sdk:all": "npm run generate:sdk:python && npm run generate:sdk:typescript && npm run generate:docs"
3031
},
3132
"keywords": [],
3233
"author": "",
@@ -48,8 +49,10 @@
4849
"@types/cors": "^2.8.19",
4950
"@types/jest": "^30.0.0",
5051
"@types/node": "^25.0.3",
52+
"handlebars": "^4.7.8",
5153
"identity-obj-proxy": "^3.0.0",
54+
"js-yaml": "^3.14.2",
5255
"ts-jest": "^29.4.6",
5356
"typescript": "^5.9.3"
5457
}
55-
}
58+
}

package-lock.json

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)