# Nexus API Usage Examples for Plugin Developers > Practical examples for using the Entropia Nexus API in plugins --- ## Table of Contents 1. [Basic Search Examples](#basic-search-examples) 2. [Entity Type-Specific Searches](#entity-type-specific-searches) 3. [Item Details & Market Data](#item-details--market-data) 4. [Complete Plugin Examples](#complete-plugin-examples) 5. [Advanced Usage Patterns](#advanced-usage-patterns) --- ## Basic Search Examples ### Simple Item Search ```python from plugins.base_plugin import BasePlugin class MyPlugin(BasePlugin): def find_weapons(self): # Search for items containing "ArMatrix" results = self.nexus_search("ArMatrix", entity_type="items") for item in results: print(f"Found: {item['name']} ({item['type']})") ``` ### Search with Limit ```python def find_top_results(self, query): # Get up to 50 results results = self.nexus_search( query, entity_type="items", limit=50 ) return results ``` --- ## Entity Type-Specific Searches ### Weapons ```python def find_laser_weapons(self): """Search for laser weapons.""" results = self.nexus_search("laser", entity_type="weapons") weapons = [] for item in results: details = self.nexus_get_item_details(item['id']) if details: weapons.append({ 'name': details['name'], 'damage': details.get('damage', 0), 'range': details.get('range', 0), 'decay': details.get('decay', 0) }) return weapons ``` ### Mobs/Creatures ```python def find_mobs_by_name(self, name): """Search for creatures.""" results = self.nexus_search(name, entity_type="mobs") mobs = [] for mob in results: mobs.append({ 'name': mob['name'], 'id': mob['id'], 'hitpoints': mob['data'].get('hitpoints', 'Unknown'), 'threat': mob['data'].get('threat', 'Unknown') }) return mobs # Usage drakabas = self.find_mobs_by_name("Drakaba") atrox = self.find_mobs_by_name("Atrox") ``` ### Blueprints ```python def find_crafting_blueprints(self, material_name): """Find blueprints that use a specific material.""" results = self.nexus_search(material_name, entity_type="blueprints") blueprints = [] for bp in results: details = self.nexus_get_item_details(bp['id']) if details and 'materials' in details: blueprints.append({ 'name': details['name'], 'materials': details['materials'], 'qr': details.get('qr', 1.0) }) return blueprints ``` ### Locations ```python def find_teleporters(self, planet="Calypso"): """Find teleporters on a specific planet.""" results = self.nexus_search(planet, entity_type="teleporters") teleporters = [] for tp in results: data = tp['data'] teleporters.append({ 'name': tp['name'], 'x': data.get('x'), 'y': data.get('y'), 'planet': data.get('planet', planet) }) return teleporters ``` ### Skills ```python def find_combat_skills(self): """Search for combat-related skills.""" results = self.nexus_search("", entity_type="skills") combat_skills = [ s for s in results if 'combat' in s.get('category', '').lower() ] return combat_skills ``` --- ## Item Details & Market Data ### Get Full Item Information ```python def analyze_item(self, item_id): """Get complete item analysis.""" # Get basic details details = self.nexus_get_item_details(item_id) if not details: return None # Get market data market = self.nexus_get_market_data(item_id) analysis = { 'name': details['name'], 'category': details.get('category', 'Unknown'), 'tt_value': details.get('tt_value', 0), 'weight': details.get('weight', 0), 'decay': details.get('decay', 0), } # Add weapon stats if applicable if 'damage' in details: analysis['weapon_stats'] = { 'damage': details['damage'], 'range': details.get('range', 0), 'accuracy': details.get('accuracy', 0), 'ammo': details.get('ammo_consumption', 0) } # Add market info if market: analysis['market'] = { 'markup': market.get('current_markup', 0), 'volume_24h': market.get('volume_24h', 0), 'buy_orders': len(market.get('buy_orders', [])), 'sell_orders': len(market.get('sell_orders', [])) } return analysis ``` ### Market Price Monitoring ```python def check_price_drops(self, watchlist): """Monitor items for price drops. Args: watchlist: List of {'item_id': str, 'max_price': float} """ deals = [] for watch in watchlist: market = self.nexus_get_market_data(watch['item_id']) if not market: continue current_price = market.get('current_markup', 0) if current_price <= watch['max_price']: deals.append({ 'item_id': watch['item_id'], 'item_name': market.get('item_name', 'Unknown'), 'current_price': current_price, 'target_price': watch['max_price'], 'savings': watch['max_price'] - current_price }) return deals ``` ### Compare Item Stats ```python def compare_weapons(self, weapon_ids): """Compare multiple weapons side by side.""" weapons = [] for wid in weapon_ids: details = self.nexus_get_item_details(wid) if details: dpp = self.calculate_dpp( details.get('damage', 0), details.get('ammo_consumption', 0), details.get('decay', 0) ) weapons.append({ 'name': details['name'], 'damage': details.get('damage', 0), 'range': details.get('range', 0), 'decay': details.get('decay', 0), 'dpp': dpp, 'tt': details.get('tt_value', 0) }) # Sort by DPP (damage per pec) return sorted(weapons, key=lambda w: w['dpp'], reverse=True) ``` --- ## Complete Plugin Examples ### Weapon Comparison Plugin ```python """ Weapon Comparison Plugin Compares weapons by DPP (Damage Per PEC) and other stats. """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLineEdit, QTableWidget, QTableWidgetItem, QLabel ) from plugins.base_plugin import BasePlugin class WeaponComparatorPlugin(BasePlugin): name = "Weapon Comparator" version = "1.0.0" author = "EU-Utility" description = "Compare weapons by DPP and stats" hotkey = "ctrl+shift+w" def initialize(self): self.weapon_ids = [] def get_ui(self): widget = QWidget() layout = QVBoxLayout(widget) # Search box search_layout = QHBoxLayout() self.search_input = QLineEdit() self.search_input.setPlaceholderText("Search weapons...") search_layout.addWidget(self.search_input) add_btn = QPushButton("Add to Compare") add_btn.clicked.connect(self.add_weapon) search_layout.addWidget(add_btn) layout.addLayout(search_layout) # Results table self.table = QTableWidget() self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels([ "Name", "Damage", "Range", "Decay", "DPP", "TT Value" ]) layout.addWidget(self.table) # Compare button compare_btn = QPushButton("Compare") compare_btn.clicked.connect(self.do_compare) layout.addWidget(compare_btn) return widget def add_weapon(self): query = self.search_input.text() results = self.nexus_search(query, entity_type="weapons", limit=5) if results: # Add first result self.weapon_ids.append(results[0]['id']) self.search_input.clear() self.search_input.setPlaceholderText( f"Added {results[0]['name']} ({len(self.weapon_ids)} total)" ) def do_compare(self): if len(self.weapon_ids) < 2: return # Fetch and compare weapons = [] for wid in self.weapon_ids: details = self.nexus_get_item_details(wid) if details: dpp = self.calculate_dpp( details.get('damage', 0), details.get('ammo_consumption', 0), details.get('decay', 0) ) weapons.append({ 'name': details['name'], 'damage': details.get('damage', 0), 'range': details.get('range', 0), 'decay': details.get('decay', 0), 'dpp': dpp, 'tt': details.get('tt_value', 0) }) # Sort by DPP weapons.sort(key=lambda w: w['dpp'], reverse=True) # Display self.table.setRowCount(len(weapons)) for i, w in enumerate(weapons): self.table.setItem(i, 0, QTableWidgetItem(w['name'])) self.table.setItem(i, 1, QTableWidgetItem(f"{w['damage']:.1f}")) self.table.setItem(i, 2, QTableWidgetItem(f"{w['range']:.0f}m")) self.table.setItem(i, 3, QTableWidgetItem(f"{w['decay']:.2f}")) self.table.setItem(i, 4, QTableWidgetItem(f"{w['dpp']:.2f}")) self.table.setItem(i, 5, QTableWidgetItem(f"{w['tt']:.2f} PED")) ``` ### Mob Info Plugin ```python """ Mob Information Plugin Quick lookup for creature stats and locations. """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QLabel ) from plugins.base_plugin import BasePlugin class MobInfoPlugin(BasePlugin): name = "Mob Info" version = "1.0.0" author = "EU-Utility" description = "Quick mob stats lookup" hotkey = "ctrl+shift+m" def get_ui(self): widget = QWidget() layout = QVBoxLayout(widget) # Search search_layout = QHBoxLayout() self.search_input = QLineEdit() self.search_input.setPlaceholderText("Enter mob name...") self.search_input.returnPressed.connect(self.search_mob) search_layout.addWidget(self.search_input) search_btn = QPushButton("Search") search_btn.clicked.connect(self.search_mob) search_layout.addWidget(search_btn) layout.addLayout(search_layout) # Results self.name_label = QLabel("Name: ") self.hp_label = QLabel("HP: ") self.damage_label = QLabel("Damage: ") self.threat_label = QLabel("Threat: ") self.planet_label = QLabel("Planet: ") layout.addWidget(self.name_label) layout.addWidget(self.hp_label) layout.addWidget(self.damage_label) layout.addWidget(self.threat_label) layout.addWidget(self.planet_label) layout.addStretch() return widget def search_mob(self): query = self.search_input.text() if not query: return results = self.nexus_search(query, entity_type="mobs", limit=1) if not results: self.name_label.setText("Mob not found") return mob = results[0] data = mob.get('data', {}) self.name_label.setText(f"Name: {mob['name']}") self.hp_label.setText(f"HP: {data.get('hitpoints', 'Unknown')}") self.damage_label.setText(f"Damage: {data.get('damage', 'Unknown')}") self.threat_label.setText(f"Threat: {data.get('threat', 'Unknown')}") self.planet_label.setText(f"Planet: {data.get('planet', 'Unknown')}") ``` ### Price Checker Plugin ```python """ Price Checker Plugin Quick market price lookup for items. """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QLabel, QFrame ) from PyQt6.QtCore import Qt from plugins.base_plugin import BasePlugin class PriceCheckerPlugin(BasePlugin): name = "Price Checker" version = "1.0.0" author = "EU-Utility" description = "Quick market price lookup" hotkey = "ctrl+shift+p" def get_ui(self): widget = QWidget() layout = QVBoxLayout(widget) # Search search_layout = QHBoxLayout() self.search_input = QLineEdit() self.search_input.setPlaceholderText("Enter item name...") self.search_input.returnPressed.connect(self.check_price) search_layout.addWidget(self.search_input) check_btn = QPushButton("Check Price") check_btn.clicked.connect(self.check_price) search_layout.addWidget(check_btn) layout.addLayout(search_layout) # Results frame self.results_frame = QFrame() results_layout = QVBoxLayout(self.results_frame) self.item_name = QLabel("Item: ") self.item_name.setStyleSheet("font-size: 14px; font-weight: bold;") results_layout.addWidget(self.item_name) self.markup_label = QLabel("Current Markup: ") results_layout.addWidget(self.markup_label) self.volume_label = QLabel("24h Volume: ") results_layout.addWidget(self.volume_label) self.range_label = QLabel("Price Range: ") results_layout.addWidget(self.range_label) layout.addWidget(self.results_frame) layout.addStretch() return widget def check_price(self): query = self.search_input.text() if not query: return # Search for item results = self.nexus_search(query, entity_type="items", limit=1) if not results: self.item_name.setText("Item not found") return item = results[0] self.item_name.setText(f"Item: {item['name']}") # Get market data market = self.nexus_get_market_data(item['id']) if not market: self.markup_label.setText("No market data available") return markup = market.get('current_markup', 0) avg_7d = market.get('avg_markup_7d', 0) volume = market.get('volume_24h', 0) self.markup_label.setText(f"Current Markup: {markup:.1f}%") self.volume_label.setText(f"24h Volume: {volume}") # Calculate range from orders buy_orders = market.get('buy_orders', []) sell_orders = market.get('sell_orders', []) if buy_orders and sell_orders: highest_buy = max(o['price'] for o in buy_orders) lowest_sell = min(o['price'] for o in sell_orders) self.range_label.setText( f"Price Range: {highest_buy:.2f} - {lowest_sell:.2f} PED" ) ``` --- ## Advanced Usage Patterns ### Caching Results ```python class CachedSearchPlugin(BasePlugin): def initialize(self): self._cache = {} self._cache_ttl = 300 # 5 minutes def cached_search(self, query, entity_type="items"): """Search with local caching.""" cache_key = f"{entity_type}:{query}" now = time.time() # Check cache if cache_key in self._cache: result, timestamp = self._cache[cache_key] if now - timestamp < self._cache_ttl: return result # Fetch fresh results = self.nexus_search(query, entity_type) self._cache[cache_key] = (results, now) return results ``` ### Batch Processing ```python def analyze_multiple_items(self, item_names): """Process multiple items efficiently.""" analyses = [] for name in item_names: # Search results = self.nexus_search(name, entity_type="items", limit=1) if not results: continue # Get details details = self.nexus_get_item_details(results[0]['id']) if not details: continue # Get market market = self.nexus_get_market_data(results[0]['id']) analyses.append({ 'search_name': name, 'found_name': details['name'], 'tt_value': details.get('tt_value', 0), 'markup': market.get('current_markup', 0) if market else 0 }) return analyses ``` ### Error Handling ```python def safe_search(self, query, entity_type="items"): """Search with error handling.""" try: if not self.nexus_is_available(): print("Nexus API not available") return [] results = self.nexus_search(query, entity_type) return results except Exception as e: print(f"Search error: {e}") return [] def safe_get_details(self, item_id): """Get details with fallback.""" try: details = self.nexus_get_item_details(item_id) return details or {'name': 'Unknown', 'id': item_id} except Exception as e: print(f"Details error: {e}") return {'name': 'Error', 'id': item_id} ``` --- ## Related Documentation - [NEXUS_API_REFERENCE.md](./NEXUS_API_REFERENCE.md) - Complete API documentation - [NEXUS_LINKTREE.md](./NEXUS_LINKTREE.md) - URL and endpoint reference - [Plugin Base Class](../plugins/base_plugin.py) - Available plugin methods --- ## Tips & Best Practices 1. **Always check for None**: `nexus_get_item_details()` and `nexus_get_market_data()` can return None 2. **Use try/except**: Wrap API calls to handle network errors gracefully 3. **Cache results**: For frequently accessed data, implement local caching 4. **Respect rate limits**: Don't make too many requests in rapid succession 5. **Check availability**: Use `nexus_is_available()` before making calls 6. **Handle both field formats**: API returns both `name` and `Name` - check both