diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..41d626a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,8 @@ +include LICENSE +include README.md +include pyproject.toml +recursive-exclude tests * +recursive-exclude docs * +recursive-exclude scripts * +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] diff --git a/README.md b/README.md index 7f7200d..581776f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ A comprehensive Python client library for the [ESO Logs API v2](https://www.esol | Metric | Status | |--------|--------| -| **Current Version** | 0.2.0-alpha | +| **Current Version** | 0.2.0a2 | | **API Coverage** | ~83% (comprehensive analysis shows 6/8 API sections fully implemented) | | **Development Stage** | Active development | | **Documentation** | [Read the Docs](https://esologs-python.readthedocs.io/) | @@ -44,25 +44,20 @@ A comprehensive Python client library for the [ESO Logs API v2](https://www.esol ## Installation -**Note**: This package is currently in development and not yet published to PyPI. - -### Current Installation Method - ```bash -# Clone the repository -git clone https://github.com/knowlen/esologs-python.git -cd esologs-python +# Install from PyPI (recommended) +pip install esologs-python -# Basic installation -pip install --upgrade pip -pip install -e . +# For development or latest features +pip install git+https://github.com/knowlen/esologs-python.git@main ``` ### Development Installation -For development with testing, linting, and pre-commit hooks: ```bash -# Development installation +# Clone for development +git clone https://github.com/knowlen/esologs-python.git +cd esologs-python pip install -e ".[dev]" ``` @@ -95,7 +90,7 @@ For comprehensive documentation, visit [esologs-python.readthedocs.io](https://e ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def main(): # Get authentication token @@ -128,7 +123,7 @@ asyncio.run(main()) ### Authentication Only ```python -from access_token import get_access_token +from esologs.auth import get_access_token # Using environment variables token = get_access_token() @@ -146,7 +141,7 @@ token = get_access_token( import asyncio from esologs.client import Client from esologs.enums import CharacterRankingMetricType, RoleType -from access_token import get_access_token +from esologs.auth import get_access_token async def main(): token = get_access_token() @@ -186,7 +181,7 @@ asyncio.run(main()) ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def main(): token = get_access_token() @@ -315,6 +310,7 @@ esologs-python/ ├── esologs/ # Main package │ ├── client.py # Main client implementation │ ├── async_base_client.py # Base async GraphQL client +│ ├── auth.py # OAuth2 authentication module │ ├── exceptions.py # Custom exceptions │ ├── validators.py # Parameter validation utilities │ └── get_*.py # Generated GraphQL query modules @@ -324,7 +320,6 @@ esologs-python/ │ ├── docs/ # Documentation tests (98 tests) │ └── sanity/ # Sanity tests (19 tests) ├── docs/ # Documentation source -├── access_token.py # OAuth2 authentication ├── schema.graphql # GraphQL schema ├── queries.graphql # GraphQL queries ├── pyproject.toml # Project configuration diff --git a/docs/api-reference/character-data.md b/docs/api-reference/character-data.md index 4844407..0b68011 100644 --- a/docs/api-reference/character-data.md +++ b/docs/api-reference/character-data.md @@ -35,7 +35,7 @@ Enables the retrieval of single characters or filtered collections of characters ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_character_profile(): token = get_access_token() @@ -99,7 +99,7 @@ Guild Rank: 0 ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_character_recent_reports(): token = get_access_token() @@ -151,7 +151,7 @@ Showing 5 reports: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_character_encounter_ranking(): token = get_access_token() @@ -213,7 +213,7 @@ Available data: ['bestAmount', 'medianPerformance', 'averagePerformance', 'total ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_character_encounter_rankings(): token = get_access_token() @@ -285,7 +285,7 @@ Rank percentile: 68.0% ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_character_zone_rankings(): token = get_access_token() @@ -324,7 +324,7 @@ Available metrics: ['bestPerformanceAverage', 'medianPerformanceAverage', 'diffi ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def analyze_character(character_id: int): """Complete character analysis including profile and recent activity.""" @@ -365,7 +365,7 @@ Recent activity: 286 reports ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def track_character_performance(character_id: int, encounter_id: int): """Track character performance for a specific encounter.""" diff --git a/docs/api-reference/game-data.md b/docs/api-reference/game-data.md index 6d9e0f9..72ffe60 100644 --- a/docs/api-reference/game-data.md +++ b/docs/api-reference/game-data.md @@ -33,7 +33,7 @@ Access collections of data such as NPCs, classes, abilities, items, maps, etc. G ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_all_abilities(): token = get_access_token() @@ -98,7 +98,7 @@ except GraphQLClientHttpError as e: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_ability_details(): token = get_access_token() @@ -145,7 +145,7 @@ ID: 2 ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_character_classes(): token = get_access_token() @@ -196,7 +196,7 @@ Available character classes: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_class_details(): token = get_access_token() @@ -240,7 +240,7 @@ Class: Dragonknight ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def browse_items(): token = get_access_token() @@ -290,7 +290,7 @@ Found 3 items ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_item_details(): token = get_access_token() @@ -342,7 +342,7 @@ ID: 3 ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_npcs(): token = get_access_token() @@ -392,7 +392,7 @@ Found 5 NPCs ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_npc_details(): token = get_access_token() @@ -440,7 +440,7 @@ ID: 1 ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_maps(): token = get_access_token() @@ -490,7 +490,7 @@ Found 100 maps (first page) ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_map_details(): token = get_access_token() @@ -536,7 +536,7 @@ ID: 1 ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_factions(): token = get_access_token() @@ -572,7 +572,7 @@ Efficiently collect and store item information for analysis: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def build_item_database(): token = get_access_token() @@ -646,7 +646,7 @@ async def respectful_bulk_operation(): ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def monitor_usage(): token = get_access_token() diff --git a/docs/api-reference/guild-data.md b/docs/api-reference/guild-data.md index 0c75015..fbe640f 100644 --- a/docs/api-reference/guild-data.md +++ b/docs/api-reference/guild-data.md @@ -34,7 +34,7 @@ Enables the retrieval of single guilds or filtered collections of guilds. Guild ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_guild_info(): token = get_access_token() @@ -88,7 +88,7 @@ Region: North America ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_guild_reports(): token = get_access_token() @@ -139,7 +139,7 @@ Guild-related filtering is also available in the main search methods: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def search_guild_reports(): token = get_access_token() @@ -178,7 +178,7 @@ Track guild performance over time: import asyncio from datetime import datetime, timedelta from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def analyze_guild_performance(): token = get_access_token() @@ -236,7 +236,7 @@ Monitor guild member participation using report rankings data: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def track_member_activity(): token = get_access_token() @@ -340,7 +340,7 @@ Unlike some APIs that throw exceptions for missing data, guild methods return `N ```python from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def handle_missing_guild(): token = get_access_token() diff --git a/docs/api-reference/report-analysis.md b/docs/api-reference/report-analysis.md index 7c0bdbc..f302352 100644 --- a/docs/api-reference/report-analysis.md +++ b/docs/api-reference/report-analysis.md @@ -60,7 +60,7 @@ Access detailed (behavioral) combat log data including events, performance graph import asyncio from esologs.client import Client from esologs.enums import EventDataType -from access_token import get_access_token +from esologs.auth import get_access_token async def analyze_report_events(): token = get_access_token() @@ -147,7 +147,7 @@ More data available after: 264591.0 import asyncio from esologs.client import Client from esologs.enums import GraphDataType -from access_token import get_access_token +from esologs.auth import get_access_token async def get_damage_graph(): token = get_access_token() @@ -230,7 +230,7 @@ Data points: 240 import asyncio from esologs.client import Client from esologs.enums import TableDataType -from access_token import get_access_token +from esologs.auth import get_access_token async def get_damage_table(): token = get_access_token() @@ -292,7 +292,7 @@ Number of players: 10 import asyncio from esologs.client import Client from esologs.enums import ReportRankingMetricType -from access_token import get_access_token +from esologs.auth import get_access_token async def get_dps_rankings(): token = get_access_token() @@ -360,7 +360,7 @@ Top DPS Players: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_player_performance(): token = get_access_token() @@ -433,7 +433,7 @@ Combine different analysis methods for comprehensive performance review: import asyncio from esologs.client import Client from esologs.enums import GraphDataType, TableDataType, ReportRankingMetricType -from access_token import get_access_token +from esologs.auth import get_access_token async def comprehensive_analysis(): token = get_access_token() @@ -509,7 +509,7 @@ Analyze specific phases of boss encounters: import asyncio from esologs.client import Client from esologs.enums import EventDataType, GraphDataType -from access_token import get_access_token +from esologs.auth import get_access_token async def analyze_encounter_phase(): token = get_access_token() diff --git a/docs/api-reference/report-search.md b/docs/api-reference/report-search.md index fb6544b..9a1fb65 100644 --- a/docs/api-reference/report-search.md +++ b/docs/api-reference/report-search.md @@ -83,7 +83,7 @@ Search and filter combat reports with advanced criteria including guilds, encoun ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def search_recent_reports(): token = get_access_token() @@ -136,7 +136,7 @@ Has more pages: True import asyncio import time from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def search_with_filters(): token = get_access_token() @@ -214,7 +214,7 @@ except GraphQLClientHttpError as e: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_guild_activity(): token = get_access_token() @@ -266,7 +266,7 @@ Guild has 10 recent reports ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_user_activity(): token = get_access_token() diff --git a/docs/api-reference/system.md b/docs/api-reference/system.md index 8b13e2c..b08a6ed 100644 --- a/docs/api-reference/system.md +++ b/docs/api-reference/system.md @@ -27,7 +27,7 @@ Monitor API usage, handle rate limits, and manage authentication. ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def check_rate_limits(): token = get_access_token() @@ -63,7 +63,7 @@ Handle authentication failures and token expiration: import asyncio from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError -from access_token import get_access_token +from esologs.auth import get_access_token async def handle_auth_errors(): try: @@ -108,7 +108,7 @@ Handle rate limit exceeded scenarios: import asyncio from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError -from access_token import get_access_token +from esologs.auth import get_access_token async def handle_rate_limits(): token = get_access_token() @@ -151,7 +151,7 @@ import asyncio from esologs.client import Client from esologs.exceptions import GraphQLClientGraphQLError, GraphQLClientGraphQLMultiError from pydantic import ValidationError -from access_token import get_access_token +from esologs.auth import get_access_token async def handle_graphql_errors(): token = get_access_token() @@ -188,7 +188,7 @@ import asyncio import httpx from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError -from access_token import get_access_token +from esologs.auth import get_access_token async def handle_network_errors(): token = get_access_token() @@ -226,7 +226,7 @@ Monitor your usage throughout a session: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token class RateLimitMonitor: def __init__(self, client): @@ -294,7 +294,7 @@ import asyncio import random from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError -from access_token import get_access_token +from esologs.auth import get_access_token async def robust_api_call(client, operation, max_retries=3): """ @@ -366,7 +366,7 @@ Manage long-running sessions with periodic health checks: import asyncio from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError -from access_token import get_access_token +from esologs.auth import get_access_token class APISession: def __init__(self): diff --git a/docs/api-reference/world-data.md b/docs/api-reference/world-data.md index 6e08696..e3e3f26 100644 --- a/docs/api-reference/world-data.md +++ b/docs/api-reference/world-data.md @@ -40,7 +40,7 @@ Access world information including encounters, zones, regions, and dungeon/trial ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_zones(): token = get_access_token() @@ -127,7 +127,7 @@ Arenas (ID: 30) ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def list_regions(): token = get_access_token() @@ -182,7 +182,7 @@ Europe (ID: 2) ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def get_dungeon_encounters(): token = get_access_token() @@ -238,7 +238,7 @@ Find all encounters across all zones: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def discover_all_encounters(): token = get_access_token() @@ -291,7 +291,7 @@ Find all zones that offer Veteran Hard Mode difficulty: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def analyze_veteran_hard_mode_zones(): token = get_access_token() diff --git a/docs/authentication.md b/docs/authentication.md index 9b848cf..67dec30 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -124,7 +124,7 @@ ESOLOGS_SECRET=your_client_secret_here For testing or specific use cases, you can pass credentials directly: ```python -from access_token import get_access_token +from esologs.auth import get_access_token # Direct parameter passing (not recommended for production) token = get_access_token( @@ -138,7 +138,7 @@ token = get_access_token( ### Basic Authentication ```python -from access_token import get_access_token +from esologs.auth import get_access_token # Get access token using environment variables token = get_access_token() @@ -151,7 +151,7 @@ print(f"Access token: {token[:20]}...") # Show first 20 chars ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def main(): # Get authentication token @@ -175,7 +175,7 @@ asyncio.run(main()) ```python import asyncio -from access_token import get_access_token +from esologs.auth import get_access_token from esologs.client import Client from esologs.exceptions import GraphQLClientHttpError @@ -241,7 +241,7 @@ Verify your token is working: ```python import asyncio from esologs.client import Client -from access_token import get_access_token +from esologs.auth import get_access_token async def validate_token(): """Validate authentication token by making a simple API call.""" @@ -364,7 +364,7 @@ Enable debug logging to troubleshoot issues: ```python import logging -from access_token import get_access_token +from esologs.auth import get_access_token # Enable debug logging logging.basicConfig(level=logging.DEBUG) diff --git a/docs/changelog.md b/docs/changelog.md index 4b993e2..b8d2004 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,20 @@ All notable changes to ESO Logs Python will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0a2] - 2025-07-16 + +### Fixed + +- **CRITICAL**: Moved authentication module (`access_token.py`) into the package as `esologs.auth` so it's included in pip distributions +- Updated all imports to use `from esologs.auth import get_access_token` or `from esologs import get_access_token` +- Authentication is now properly packaged and accessible when installing from PyPI + +## [0.2.0a1] - 2025-07-15 + +### Added + +This is the first alpha release of version 0.2.0. See the [0.2.0] section below for full feature list. + ## [0.2.0] - 2024-01-XX (Upcoming Release) ### Added diff --git a/docs/development/architecture.md b/docs/development/architecture.md index 19f357c..fde1437 100644 --- a/docs/development/architecture.md +++ b/docs/development/architecture.md @@ -60,7 +60,7 @@ class Client(BaseClient): **Purpose**: OAuth2 client credentials flow for secure API access ```python -# access_token.py +# esologs/auth.py def get_access_token(client_id=None, client_secret=None): """Get OAuth2 access token using client credentials flow.""" @@ -316,7 +316,7 @@ TEST_DATA = { ```toml [project] name = "esologs-python" -version = "0.2.0-alpha" +version = "0.2.0a2" dependencies = [ "httpx>=0.24.0", "pydantic>=2.0.0", diff --git a/docs/development/setup.md b/docs/development/setup.md index a611981..50b4f2d 100644 --- a/docs/development/setup.md +++ b/docs/development/setup.md @@ -74,10 +74,11 @@ pytest # Run all tests ``` esologs-python/ -├── esologs/ # Generated GraphQL client +├── esologs/ # Main package +│ ├── auth.py # OAuth2 authentication +│ └── *.py # Client and generated modules ├── tests/ # Test suites (see Testing Guide) ├── docs/ # Documentation source -├── access_token.py # OAuth2 authentication ├── queries.graphql # GraphQL queries to generate ├── schema.graphql # ESO Logs API schema └── mini.toml # Code generation config diff --git a/docs/index.md b/docs/index.md index de3256b..cae3cda 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,11 +23,12 @@ === "Installation" ```bash - # Clone the repository + # Install from PyPI + pip install esologs-python + + # Or install latest development version git clone https://github.com/knowlen/esologs-python.git cd esologs-python - - # Install the package pip install -e . ``` @@ -44,7 +45,7 @@ ```python import asyncio from esologs.client import Client - from access_token import get_access_token + from esologs.auth import get_access_token async def main(): token = get_access_token() @@ -72,7 +73,7 @@
v0.2.0-alpha
+
v0.2.0a2
83% API Coverage
Active development with comprehensive testing and documentation.