{"id":18286418,"url":"https://github.com/kamilrybacki/ppeagent","last_synced_at":"2026-05-12T12:41:47.372Z","repository":{"id":234416444,"uuid":"788852393","full_name":"kamilrybacki/PPEAgent","owner":"kamilrybacki","description":"An agent application to fetch data from Energa Operator electric energy meters","archived":false,"fork":false,"pushed_at":"2024-04-24T08:03:29.000Z","size":153,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T06:30:25.845Z","etag":null,"topics":["api-rest","data-scraping","fastapi","microservice","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kamilrybacki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-19T08:01:14.000Z","updated_at":"2024-06-18T08:14:13.000Z","dependencies_parsed_at":"2025-04-09T06:37:42.394Z","dependency_job_id":null,"html_url":"https://github.com/kamilrybacki/PPEAgent","commit_stats":null,"previous_names":["kamilrybacki/ppeagent"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/kamilrybacki/PPEAgent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamilrybacki%2FPPEAgent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamilrybacki%2FPPEAgent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamilrybacki%2FPPEAgent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamilrybacki%2FPPEAgent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kamilrybacki","download_url":"https://codeload.github.com/kamilrybacki/PPEAgent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kamilrybacki%2FPPEAgent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274026689,"owners_count":25209739,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-rest","data-scraping","fastapi","microservice","python3"],"created_at":"2024-11-05T13:20:10.692Z","updated_at":"2026-05-12T12:41:47.332Z","avatar_url":"https://github.com/kamilrybacki.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PPEAgent\n\n\u003cimg\n    src='.github/assets/images/PPEAgent.svg'\n    alt='PPE agent logo'\n    width='200'\n    style='display: block; margin: 0 auto;'\n/\u003e\n\n![GitHub last commit](https://img.shields.io/github/last-commit/kamilrybacki/PPEAgent)\n![GitHub issues](https://img.shields.io/github/issues/kamilrybacki/PPEAgent)\n![Linting](https://github.com/kamilrybacki/PPEAgent/actions/workflows/lint-code.yml/badge.svg)\n![Docker pulls](https://img.shields.io/docker/pulls/kokosz/ppeagent.svg)\n![Docker image size](https://img.shields.io/docker/image-size/kokosz/ppeagent/latest)\n\nThis is a Python implementation of a data scraping agent that serves a simple API\nto fetch energy consumption measurements from a single meter registered\nin the Energa Operator network.\n\nThe main goals of this project are:\n\n1. Provide an isolated service that acts as a simple middleware between the\n   Energa Operator API and some other application that needs to consume\n   and post-process the data,\n2. Slightly simplify the data structure returned by the Energa Operator API,\n3. Return JSON data that is easier to consume by other applications,\n4. Require as little configuration as possible to run the service.\n\nThe API is implemented using the [FastAPI] framework and served using [Uvicorn].\n\n## Requirements\n\n* Python 3.12+,\n* `fastapi==0.110.2`,\n* `annotated-types==0.6.0`,\n* `anyio==4.3.0`,\n* `idna==3.7`,\n* `pydantic==2.7.0`,\n* `pydantic-core==2.18.1`,\n* `sniffio==1.3.1`,\n* `starlette==0.37.2`,\n* `click==8.1.7`,\n* `h11==0.14.0`,\n* `httptools==0.6.1`,\n* `python-dotenv==1.0.1`,\n* `pyyaml==6.0.1`,\n* `uvicorn==0.29.0`,\n* `uvloop==0.19.0`,\n* `watchfiles==0.21.0`,\n* `websockets==12.0`,\n* `certifi==2024.2.2`,\n* `charset-normalizer==3.3.2`,\n* `requests==2.31.0`,\n* `urllib3==2.2.1`,\n* `configparser==7.0.0`.\n\n## Usage\n\nThere are a couple of settings that need to be configured before running the application, with the main ones being Your Energa Operator account info.\n\n### Configuration\n\nBelow is a list of **environment variables** that control the main settings of the application run:\n\n#### Required\n\n* `PPE_AGENT_EMAIL` - Your Energa [*MójLicznik*] account email,\n* `PPE_AGENT_PASSWORD` - Your Energa [*MójLicznik*] account password.\n\n#### Optional\n\n* `PPE_AGENT_HOST` - Hostname on which the application will listen for incoming requests (default: `'127.0.0.1'` on local deployments, `'0.0.0.0'` in Docker containers),\n* `PPE_AGENT_PORT` - Port on which the application will listen for incoming requests (default: 8000),\n* `PPE_AGENT_CONFIG` - path to the configuration file (default: `''` i.e. reads hardcoded defaults).\n\n**Note**: These are the only required environment variables and are obtained by registering an account on the [*MójLicznik*] website - **not** anywhere from Your contract with Energa Operator.\n\n#### Extra configuration\n\nThe rest of the configuration is optional and can be set in the *.cfg* file pointed to by the `PPE_AGENT_CONFIG` environment variable:\n\n* `GENERAL_LOGGING_FORMAT` - format of log entries reported by Uvicorn (default: `'{asctime} [{processName}] {levelname}: {message}'`),\n* `GENERAL_ASSETS_PATH` - path to the directory where the application will store its static assets (default: '`'assets'`' in the repository source code directory),\n* `GENERAL_MAX_RETRIES` - maximum number of retries for certain operations (external requests, I/O operations etc. see the [`retry_procedure` context manager]) (default: 3),\n* `AGENT_TIMEOUT` - default timeout in seconds for requests to the Energa Operator API (default: 10),\n* `AGENT_ROOT_PATH` - root path of the API served by the application (default: `'/'`).\n\n### Running the application\n\nThere are two ways to run this application: locally and in a Docker container.\nThe preferred way is to simply spawn a Docker container, as it requires less\nconfiguration and corresponds to the intended use case of this application.\n\nHowever, if you want to run the application locally (e.g. for quick testing or modification purposes), both methods are described below.\n\n#### Local installation\n\nTo install the required dependencies **locally**, run:\n\n```shell\npip install -r requirements.txt\n```\n\nNext, simply spawn a Uvicorn ASGI server by running the `serve.py` script:\n\n```shell\npython serve.py\n```\n\nThis should result in a new Uvicorn process spawning in the terminal as so:\n\n\u003cimg src=\".github/assets/images/ASGI.png\" alt=\"Terminal logs of running agent\"/\u003e\n\n#### Docker image\n\nA more pro-Gamer move :joystick: is to deploy this application in a Docker container.\n\nThis repository provides a [Dockerfile] that installs the required dependencies and sets up the application to run in a container.\n\nTo build the Docker image, run the following command in the repository root directory:\n\n```bash\ndocker build -t \"\u003cIMAGE NAME\u003e\" .\n```\n\n**But** there is an even more sophisticated approach - the official image is available on Docker Hub, so you can pull it directly from there:\n\n```bash\ndocker pull kokosz/ppeagent\n```\n\nAfter building the image or pulling it from Docker Hub, you can run the container by executing the following command:\n\n```bash\ndocker \\\n    run \\\n        -p 8000:8000 \\ \n        --volume \\\n            \"\u003cPATH TO YOUR CONFIG FILE\u003e:/app/config.cfg\" \\\n        --env \\\n            PPE_AGENT_CONFIG=\"/app/config.cfg\" \\\n        --env \\\n            PPE_AGENT_EMAIL=\"\u003cYOUR EMAIL FOR MOJLICZNIK\u003e\" \\\n        --env \\\n            PPE_AGENT_PASSWORD=\"\u003cYOUR PASSWORD FOR MOJLICZNIK\u003e\" \\\n        --env \\\n            PPE_AGENT_PORT=8000 \\\n        kokosz/ppeagent\n```\n\nNote that You can omit the volume mount of the custom configuration file if you don't need it and leave the `PPE_AGENT_CONFIG` environment variable empty.\n\n**Hint**: If you want to test out passing the configuration file to the container, you can use the provided `example.cfg` file in the repository root directory.\nBe sure to run the Docker container from the repository root path (there are some relative paths in the configuration file). 😉\n\n### Endpoints\n\nThe application exposes right now a small set of API endpoints for fetching data from PPEAgent. All of the subpaths presented below are relative to Your deployment root path (`AGENT_ROOT_PATH`):\n\n* (GET) `/` - returns a micro HTML welcome page,\n* (GET) `/energy/info` - provides Basi information about querying energy consumption data,\n* (GET) `/energy/query` - main endpoints for fetching data from Your meter. This endpoints uses the following query parameters:\n  * `date` - the target date for which you want to obtain measurements (in `[DAY]-[MONTH]-[YEAR]` format,\n  * `period` - the magnitute of measurement period (accepted values: `day`, `week`, `month` or `year`).\n\nOptionally, you can provide the following parameters:\n\n* `limit` - the maximum number of measurements to return, starting from the most recent one (default: fetches all existing data),\n* `cost` - the cost of the energy unit (kWh) in a chosen currency - the API will return the cost of the energy consumed in the specified currency (default: shows measurements in kWh).\n\nThe data is returned according to aggregation rules defined in *MojLicznik* application i.e. based on which period the requested date lies in.\n\nFor example, if Your date lies in the 14th week of the year and chosen period type is weekly (`?period=week`) the data for the WHOLE 14th WEEK is RETURNED (or at least it looks like so 🤷)\n\n[FastAPI]: https://fastapi.tiangolo.com/\n[Uvicorn]: https://www.uvicorn.org/\n[*MójLicznik*]: https://mojlicznik.energa-operator.pl/\n[`retry_procedure` context manager]: https://github.com/kamilrybacki/PPEAgent/blob/main/src/agent/utils/retry.py\n[Dockerfile]: https://github.com/kamilrybacki/PPEAgent/blob/main/Dockerfile\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkamilrybacki%2Fppeagent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkamilrybacki%2Fppeagent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkamilrybacki%2Fppeagent/lists"}