{"id":30741195,"url":"https://github.com/slevin48/weather-scraper","last_synced_at":"2026-05-18T15:13:24.758Z","repository":{"id":305253663,"uuid":"1022368370","full_name":"slevin48/weather-scraper","owner":"slevin48","description":"GitHub Action to scrape the weather with Python, store as an Artifact and analyze with MATLAB 🌥️⛅🌦️","archived":false,"fork":false,"pushed_at":"2025-07-20T15:14:18.000Z","size":2575,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-04T00:47:29.365Z","etag":null,"topics":["actions","git-scraping","matlab","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slevin48.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2025-07-18T23:51:15.000Z","updated_at":"2025-07-30T20:02:47.000Z","dependencies_parsed_at":"2025-07-19T06:01:13.855Z","dependency_job_id":"0d11a742-bee4-471d-b078-4f50d6856134","html_url":"https://github.com/slevin48/weather-scraper","commit_stats":null,"previous_names":["slevin48/weather-scraper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/slevin48/weather-scraper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slevin48%2Fweather-scraper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slevin48%2Fweather-scraper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slevin48%2Fweather-scraper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slevin48%2Fweather-scraper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slevin48","download_url":"https://codeload.github.com/slevin48/weather-scraper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slevin48%2Fweather-scraper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33181996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-18T09:27:30.708Z","status":"ssl_error","status_checked_at":"2026-05-18T09:27:28.300Z","response_time":71,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["actions","git-scraping","matlab","python"],"created_at":"2025-09-04T00:45:34.392Z","updated_at":"2026-05-18T15:13:19.751Z","avatar_url":"https://github.com/slevin48.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Weather actions\n\nGitHub Action to scrape the weather️\n\n\n![image_0.png](README_media/image_0.png)\n\n\u003ca name=\"beginToc\"\u003e\u003c/a\u003e\n\n## Table of Contents\n\u0026emsp;\u0026emsp;[Intro](#intro)\n \n\u0026emsp;\u0026emsp;[Setup](#setup)\n \n\u0026emsp;\u0026emsp;[PyGitHub](#pygithub)\n \n\u0026emsp;\u0026emsp;[Artifacts](#artifacts)\n \n\u0026emsp;\u0026emsp;[Retime](#retime)\n \n\u003ca name=\"endToc\"\u003e\u003c/a\u003e\n\n## Intro\n\nGitHub Actions enable to trigger workflows on schedule.\n\n\nThis is the syntax used in order to scrape the weather.\n\n```\n┌───────────── minute (*/10 → every 10 minutes)\n│ ┌─────────── hour   (*   → every hour)\n│ │ ┌───────── day     (*   → every day of month)\n│ │ │ ┌─────── month   (*   → every month)\n│ │ │ │ ┌───── weekday (*   → every day of week)\n│ │ │ │ │\n*/10 * * * *\n```\n\nBut the precision of the scheduler isn't great, so retiming will be necessary in post\\-processing.\n\n\nThis script will retrieve Artifacts from GitHub Actions that scraped openweathermap.\n\n## Setup\n\nThis setup step is specific to MATLAB Online, retrieving \n\n```matlab\nif matlab.internal.environment.context.isMATLABOnline\n    setup_python\nend\n```\n\nConnect to Python in Out\\-Of\\-Process execution mode (to enable the termination of the environment without logging out of MATLAB Online)\n\n```matlab\npe = pyenv(ExecutionMode=\"OutOfProcess\")\n```\n\n```matlabTextOutput\npe = \n  PythonEnvironment with properties:\n\n          Version: \"3.10\"\n       Executable: \"/usr/bin/python3\"\n          Library: \"libpython3.10.so.1.0\"\n             Home: \"/usr\"\n           Status: NotLoaded\n    ExecutionMode: OutOfProcess\n\n```\n\nCreate a GitHub [Personal Access Token](https://github.com/settings/personal-access-tokens/new) with permission to the repo actions (read only), and save it as a variable  `GITHUB_TOKEN` in  a file called `.env`\n\n```matlab\nloadenv(\".env\")\ntoken = getenv(\"GITHUB_TOKEN\");\n```\n\n## PyGitHub\n```matlab\ng = py.github.Github(token);\nrepo = g.get_repo(\"slevin48/weather-scraper\")\n```\n\n```matlabTextOutput\nrepo = \n  Python Repository with properties:\n\n                  allow_auto_merge: [1x1 py.NoneType]\n                     allow_forking: 1\n                allow_merge_commit: [1x1 py.NoneType]\n                allow_rebase_merge: [1x1 py.NoneType]\n                allow_squash_merge: [1x1 py.NoneType]\n               allow_update_branch: [1x1 py.NoneType]\n          anonymous_access_enabled: [1x1 py.NoneType]\n                       archive_url: [1x76 py.str]\n                          archived: 0\n                     assignees_url: [1x70 py.str]\n                         blobs_url: [1x69 py.str]\n                      branches_url: [1x71 py.str]\n                         clone_url: [1x47 py.str]\n                   code_of_conduct: [1x1 py.NoneType]\n                 collaborators_url: [1x82 py.str]\n                      comments_url: [1x71 py.str]\n                       commits_url: [1x67 py.str]\n                       compare_url: [1x77 py.str]\n                         completed: 1\n                      contents_url: [1x70 py.str]\n                  contributors_url: [1x66 py.str]\n                        created_at: [1x1 py.datetime.datetime]\n                 custom_properties: [1x1 py.NoneType]\n                    default_branch: [1x4 py.str]\n            delete_branch_on_merge: [1x1 py.NoneType]\n                   deployments_url: [1x65 py.str]\n                       description: [1x41 py.str]\n                          disabled: 0\n                     downloads_url: [1x63 py.str]\n                              etag: [1x68 py.str]\n                        events_url: [1x60 py.str]\n                              fork: 0\n                             forks: [1x1 py.int]\n                       forks_count: [1x1 py.int]\n                         forks_url: [1x59 py.str]\n                         full_name: [1x24 py.str]\n                   git_commits_url: [1x71 py.str]\n                      git_refs_url: [1x68 py.str]\n                      git_tags_url: [1x68 py.str]\n                           git_url: [1x45 py.str]\n                   has_discussions: 0\n                     has_downloads: 1\n                        has_issues: 1\n                         has_pages: 0\n                      has_projects: 1\n                          has_wiki: 1\n                          homepage: [1x0 py.str]\n                         hooks_url: [1x59 py.str]\n                          html_url: [1x43 py.str]\n                                id: [1x1 py.int]\n                       is_template: 0\n                 issue_comment_url: [1x78 py.str]\n                  issue_events_url: [1x76 py.str]\n                        issues_url: [1x69 py.str]\n                          keys_url: [1x67 py.str]\n                        labels_url: [1x67 py.str]\n                          language: [1x6 py.str]\n                     languages_url: [1x63 py.str]\n                     last_modified: [1x29 py.str]\n            last_modified_datetime: [1x1 py.datetime.datetime]\n                           license: [1x1 py.NoneType]\n                     master_branch: [1x1 py.NoneType]\n              merge_commit_message: [1x1 py.NoneType]\n                merge_commit_title: [1x1 py.NoneType]\n                        merges_url: [1x60 py.str]\n                    milestones_url: [1x73 py.str]\n                        mirror_url: [1x1 py.NoneType]\n                              name: [1x15 py.str]\n                     network_count: [1x1 py.int]\n                           node_id: [1x12 py.str]\n                 notifications_url: [1x93 py.str]\n                       open_issues: [1x1 py.int]\n                 open_issues_count: [1x1 py.int]\n                      organization: [1x1 py.NoneType]\n                             owner: [1x1 py.github.NamedUser.NamedUser]\n                            parent: [1x1 py.NoneType]\n                       permissions: [1x1 py.github.Permissions.Permissions]\n                           private: 0\n                         pulls_url: [1x68 py.str]\n                         pushed_at: [1x1 py.datetime.datetime]\n                          raw_data: [1x1 py.dict]\n                       raw_headers: [1x1 py.dict]\n                      releases_url: [1x67 py.str]\n                         requester: [1x1 py.github.Requester.Requester]\n                         role_name: [1x1 py.NoneType]\n             security_and_analysis: [1x1 py.NoneType]\n                              size: [1x1 py.int]\n                            source: [1x1 py.NoneType]\n       squash_merge_commit_message: [1x1 py.NoneType]\n         squash_merge_commit_title: [1x1 py.NoneType]\n                           ssh_url: [1x43 py.str]\n                  stargazers_count: [1x1 py.int]\n                    stargazers_url: [1x64 py.str]\n                        starred_at: [1x1 py.NoneType]\n                      statuses_url: [1x68 py.str]\n                 subscribers_count: [1x1 py.int]\n                   subscribers_url: [1x65 py.str]\n                  subscription_url: [1x66 py.str]\n                           svn_url: [1x43 py.str]\n                          tags_url: [1x58 py.str]\n                         teams_url: [1x59 py.str]\n                  temp_clone_token: [1x1 py.NoneType]\n               template_repository: [1x1 py.NoneType]\n                            topics: [1x2 py.list]\n                         trees_url: [1x69 py.str]\n                        updated_at: [1x1 py.datetime.datetime]\n                               url: [1x53 py.str]\n    use_squash_pr_title_as_default: [1x1 py.NoneType]\n                        visibility: [1x6 py.str]\n                          watchers: [1x1 py.int]\n                    watchers_count: [1x1 py.int]\n       web_commit_signoff_required: 0\n\n    Repository(full_name=\"slevin48/weather-scraper\")\n\n```\n\n```matlab\n% repo.get_contents(\"README.md\").decoded_content.decode(\"utf-8\")\n```\n\nFetch successful workflow runs from the repository\n\n```matlab\nsuccessful_runs = repo.get_workflow_runs(status=\"success\")\n```\n\n```matlabTextOutput\nsuccessful_runs = \n  Python PaginatedList with properties:\n\n    is_graphql: 0\n       is_rest: 1\n      reversed: [1x1 py.github.PaginatedList.PaginatedList]\n    totalCount: [1x1 py.int]\n\n    \u003cgithub.PaginatedList.PaginatedList object at 0x71bae2149030\u003e\n\n```\n\nBuild a list of the names and IDs of the successful runs\n\n```matlab\nruns_list = pyrun(\"runs_list = [run.id for run in successful_runs]\",\"runs_list\",successful_runs=successful_runs)\n```\n\n```matlabTextOutput\nruns_list = \n  Python list with values:\n\n    [16391395647, 16391241500, 16391191471, 16390929116, 16390804032, 16390682584, 16390456143, 16390314706, 16390229454, 16390133881, 16389964859, 16389837244, 16389786553, 16389662839, 16389486972, 16389373560, 16389306222, 16389174569, 16388929436, 16388591956, 16388389249, 16388331245, 16388266679, 16388192423, 16388067912, 16387967805, 16387917262, 16387817958, 16387621136, 16387480892, 16387434103, 16387339682, 16387183632, 16387052613, 16386929475, 16386718842, 16386555986, 16386502359, 16386397034, 16386268977, 16386124980, 16386030270, 16385781572, 16385631558, 16385578983, 16385448348, 16385194196, 16385091436, 16384870251, 16384569967, 16383763637, 16383554036, 16383510363]\n\n    Use string, double or cell function to convert to a MATLAB array.\n\n```\n\n## Artifacts\n\nPython black magic one liner extend/list comprehension (ask ChatGPT)\n\n```matlab\nartifacts_info = pyrun('artifacts_info = [];artifacts_info.extend([{**{\"run_id\": run_id, \"artifact_obj\": a}, \"artifact_id\": a.id, \"name\": a.name, \"size_in_bytes\": a.size_in_bytes, \"created_at\": a.created_at, \"expired\": a.expired} for run_id in runs_list for a in repo.get_workflow_run(run_id).get_artifacts()])', 'artifacts_info', runs_list=runs_list, repo=repo)\n```\n\n```matlabTextOutput\nartifacts_info = \n  Python list with values:\n\n    [{'run_id': 16391395647, 'artifact_obj': Artifact(name=\"boston-weather\", id=3570153600), 'artifact_id': 3570153600, 'name': 'boston-weather', 'size_in_bytes': 550, 'created_at': datetime.datetime(2025, 7, 19, 18, 12, 58, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16391241500, 'artifact_obj': Artifact(name=\"boston-weather\", id=3570118115), 'artifact_id': 3570118115, 'name': 'boston-weather', 'size_in_bytes': 546, 'created_at': datetime.datetime(2025, 7, 19, 17, 53, 4, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16391191471, 'artifact_obj': Artifact(name=\"boston-weather\", id=3570107235), 'artifact_id': 3570107235, 'name': 'boston-weather', 'size_in_bytes': 553, 'created_at': datetime.datetime(2025, 7, 19, 17, 46, 42, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390929116, 'artifact_obj': Artifact(name=\"boston-weather\", id=3570044265), 'artifact_id': 3570044265, 'name': 'boston-weather', 'size_in_bytes': 552, 'created_at': datetime.datetime(2025, 7, 19, 17, 13, 4, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390804032, 'artifact_obj': Artifact(name=\"boston-weather\", id=3570014288), 'artifact_id': 3570014288, 'name': 'boston-weather', 'size_in_bytes': 537, 'created_at': datetime.datetime(2025, 7, 19, 16, 57, 27, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390682584, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569983201), 'artifact_id': 3569983201, 'name': 'boston-weather', 'size_in_bytes': 539, 'created_at': datetime.datetime(2025, 7, 19, 16, 40, 41, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390456143, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569918720), 'artifact_id': 3569918720, 'name': 'boston-weather', 'size_in_bytes': 546, 'created_at': datetime.datetime(2025, 7, 19, 16, 11, 3, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390314706, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569882134), 'artifact_id': 3569882134, 'name': 'boston-weather', 'size_in_bytes': 544, 'created_at': datetime.datetime(2025, 7, 19, 15, 54, 20, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390229454, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569861454), 'artifact_id': 3569861454, 'name': 'boston-weather', 'size_in_bytes': 540, 'created_at': datetime.datetime(2025, 7, 19, 15, 42, 17, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16390133881, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569839810), 'artifact_id': 3569839810, 'name': 'boston-weather', 'size_in_bytes': 541, 'created_at': datetime.datetime(2025, 7, 19, 15, 29, 56, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389964859, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569801275), 'artifact_id': 3569801275, 'name': 'boston-weather', 'size_in_bytes': 542, 'created_at': datetime.datetime(2025, 7, 19, 15, 9, 21, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389837244, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569770412), 'artifact_id': 3569770412, 'name': 'boston-weather', 'size_in_bytes': 541, 'created_at': datetime.datetime(2025, 7, 19, 14, 52, 59, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389786553, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569758498), 'artifact_id': 3569758498, 'name': 'boston-weather', 'size_in_bytes': 543, 'created_at': datetime.datetime(2025, 7, 19, 14, 46, 38, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389662839, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569730162), 'artifact_id': 3569730162, 'name': 'boston-weather', 'size_in_bytes': 547, 'created_at': datetime.datetime(2025, 7, 19, 14, 31, 12, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389486972, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569688695), 'artifact_id': 3569688695, 'name': 'boston-weather', 'size_in_bytes': 546, 'created_at': datetime.datetime(2025, 7, 19, 14, 9, 57, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389373560, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569659780), 'artifact_id': 3569659780, 'name': 'boston-weather', 'size_in_bytes': 546, 'created_at': datetime.datetime(2025, 7, 19, 13, 55, 56, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389306222, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569643202), 'artifact_id': 3569643202, 'name': 'boston-weather', 'size_in_bytes': 547, 'created_at': datetime.datetime(2025, 7, 19, 13, 46, 57, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16389174569, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569611849), 'artifact_id': 3569611849, 'name': 'boston-weather', 'size_in_bytes': 539, 'created_at': datetime.datetime(2025, 7, 19, 13, 29, 45, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388929436, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569557613), 'artifact_id': 3569557613, 'name': 'boston-weather', 'size_in_bytes': 539, 'created_at': datetime.datetime(2025, 7, 19, 12, 59, 33, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388591956, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569480918), 'artifact_id': 3569480918, 'name': 'boston-weather', 'size_in_bytes': 546, 'created_at': datetime.datetime(2025, 7, 19, 12, 17, 23, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388389249, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569425716), 'artifact_id': 3569425716, 'name': 'boston-weather', 'size_in_bytes': 543, 'created_at': datetime.datetime(2025, 7, 19, 11, 51, 29, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388331245, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569411586), 'artifact_id': 3569411586, 'name': 'boston-weather', 'size_in_bytes': 544, 'created_at': datetime.datetime(2025, 7, 19, 11, 43, 31, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388266679, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569397504), 'artifact_id': 3569397504, 'name': 'boston-weather', 'size_in_bytes': 541, 'created_at': datetime.datetime(2025, 7, 19, 11, 34, 48, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388192423, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569381920), 'artifact_id': 3569381920, 'name': 'boston-weather', 'size_in_bytes': 551, 'created_at': datetime.datetime(2025, 7, 19, 11, 25, 20, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16388067912, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569356392), 'artifact_id': 3569356392, 'name': 'boston-weather', 'size_in_bytes': 555, 'created_at': datetime.datetime(2025, 7, 19, 11, 9, 15, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387967805, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569332352), 'artifact_id': 3569332352, 'name': 'boston-weather', 'size_in_bytes': 543, 'created_at': datetime.datetime(2025, 7, 19, 10, 55, 45, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387917262, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569321342), 'artifact_id': 3569321342, 'name': 'boston-weather', 'size_in_bytes': 551, 'created_at': datetime.datetime(2025, 7, 19, 10, 49, 11, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387817958, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569296345), 'artifact_id': 3569296345, 'name': 'boston-weather', 'size_in_bytes': 552, 'created_at': datetime.datetime(2025, 7, 19, 10, 35, 38, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387621136, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569248785), 'artifact_id': 3569248785, 'name': 'boston-weather', 'size_in_bytes': 552, 'created_at': datetime.datetime(2025, 7, 19, 10, 10, 5, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387480892, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569216693), 'artifact_id': 3569216693, 'name': 'boston-weather', 'size_in_bytes': 554, 'created_at': datetime.datetime(2025, 7, 19, 9, 51, 35, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387434103, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569205793), 'artifact_id': 3569205793, 'name': 'boston-weather', 'size_in_bytes': 552, 'created_at': datetime.datetime(2025, 7, 19, 9, 45, 18, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387339682, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569184319), 'artifact_id': 3569184319, 'name': 'boston-weather', 'size_in_bytes': 555, 'created_at': datetime.datetime(2025, 7, 19, 9, 32, 32, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387183632, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569149666), 'artifact_id': 3569149666, 'name': 'boston-weather', 'size_in_bytes': 554, 'created_at': datetime.datetime(2025, 7, 19, 9, 12, 25, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16387052613, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569116928), 'artifact_id': 3569116928, 'name': 'boston-weather', 'size_in_bytes': 551, 'created_at': datetime.datetime(2025, 7, 19, 8, 56, 22, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386929475, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569087235), 'artifact_id': 3569087235, 'name': 'boston-weather', 'size_in_bytes': 553, 'created_at': datetime.datetime(2025, 7, 19, 8, 40, 30, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386718842, 'artifact_obj': Artifact(name=\"boston-weather\", id=3569031298), 'artifact_id': 3569031298, 'name': 'boston-weather', 'size_in_bytes': 551, 'created_at': datetime.datetime(2025, 7, 19, 8, 12, 37, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386555986, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568988396), 'artifact_id': 3568988396, 'name': 'boston-weather', 'size_in_bytes': 551, 'created_at': datetime.datetime(2025, 7, 19, 7, 51, 14, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386502359, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568974386), 'artifact_id': 3568974386, 'name': 'boston-weather', 'size_in_bytes': 547, 'created_at': datetime.datetime(2025, 7, 19, 7, 43, 57, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386397034, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568948373), 'artifact_id': 3568948373, 'name': 'boston-weather', 'size_in_bytes': 553, 'created_at': datetime.datetime(2025, 7, 19, 7, 30, 34, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386268977, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568910975), 'artifact_id': 3568910975, 'name': 'boston-weather', 'size_in_bytes': 549, 'created_at': datetime.datetime(2025, 7, 19, 7, 14, 16, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386124980, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568869632), 'artifact_id': 3568869632, 'name': 'boston-weather', 'size_in_bytes': 549, 'created_at': datetime.datetime(2025, 7, 19, 6, 57, 30, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16386030270, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568846390), 'artifact_id': 3568846390, 'name': 'boston-weather', 'size_in_bytes': 538, 'created_at': datetime.datetime(2025, 7, 19, 6, 44, 57, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385781572, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568784555), 'artifact_id': 3568784555, 'name': 'boston-weather', 'size_in_bytes': 535, 'created_at': datetime.datetime(2025, 7, 19, 6, 14, 9, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385631558, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568741235), 'artifact_id': 3568741235, 'name': 'boston-weather', 'size_in_bytes': 548, 'created_at': datetime.datetime(2025, 7, 19, 5, 55, 14, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385578983, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568726259), 'artifact_id': 3568726259, 'name': 'boston-weather', 'size_in_bytes': 552, 'created_at': datetime.datetime(2025, 7, 19, 5, 48, 30, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385448348, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568691949), 'artifact_id': 3568691949, 'name': 'boston-weather', 'size_in_bytes': 533, 'created_at': datetime.datetime(2025, 7, 19, 5, 31, 23, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385194196, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568617287), 'artifact_id': 3568617287, 'name': 'boston-weather', 'size_in_bytes': 554, 'created_at': datetime.datetime(2025, 7, 19, 5, 0, 34, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16385091436, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568583589), 'artifact_id': 3568583589, 'name': 'boston-weather', 'size_in_bytes': 557, 'created_at': datetime.datetime(2025, 7, 19, 4, 46, 10, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16384870251, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568513288), 'artifact_id': 3568513288, 'name': 'boston-weather', 'size_in_bytes': 553, 'created_at': datetime.datetime(2025, 7, 19, 4, 17, 42, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16384569967, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568418681), 'artifact_id': 3568418681, 'name': 'boston-weather', 'size_in_bytes': 549, 'created_at': datetime.datetime(2025, 7, 19, 3, 41, 47, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16383763637, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568176563), 'artifact_id': 3568176563, 'name': 'boston-weather', 'size_in_bytes': 539, 'created_at': datetime.datetime(2025, 7, 19, 2, 3, 41, tzinfo=datetime.timezone.utc), 'expired': False}, {'run_id': 16383554036, 'artifact_obj': Artifact(name=\"boston-weather\", id=3568117727), 'artifact_id': 3568117727, 'name': 'boston-weather', 'size_in_bytes': 540, 'created_at': datetime.datetime(2025, 7, 19, 1, 40, 3, tzinfo=datetime.timezone.utc), 'expired': False}]\n\n    Use string, double or cell function to convert to a MATLAB array.\n\n```\n\n```matlab\na1 = artifacts_info{1}.get('artifact_obj')\n```\n\n```matlabTextOutput\na1 = \n  Python Artifact with properties:\n\n      archive_download_url: [1x86 py.str]\n                created_at: [1x1 py.datetime.datetime]\n                      etag: [1x68 py.str]\n                   expired: 0\n                expires_at: [1x1 py.datetime.datetime]\n                  head_sha: [1x1 py.NoneType]\n                        id: [1x1 py.int]\n             last_modified: [1x1 py.NoneType]\n    last_modified_datetime: [1x1 py.NoneType]\n                      name: [1x14 py.str]\n                   node_id: [1x28 py.str]\n                  raw_data: [1x1 py.dict]\n               raw_headers: [1x1 py.dict]\n                 requester: [1x1 py.github.Requester.Requester]\n             size_in_bytes: [1x1 py.int]\n                updated_at: [1x1 py.datetime.datetime]\n                       url: [1x82 py.str]\n              workflow_run: [1x1 py.github.WorkflowRun.WorkflowRun]\n\n    Artifact(name=\"boston-weather\", id=3570153600)\n\n```\n\n```matlab\ndf = pyrunfile(\"utils.py\",\"df\",artifacts_info=artifacts_info);\nT = table(df);\nT = sortrows(T, \"time\")\n```\n| |time|temp|feels_like|temp_min|temp_max|pressure|humidity|sea_level|grnd_level|\n|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n|1|19-Jul-2025 01:33:29|69.1300|68.9400|65.1400|71.1000|1019|68|1019|1015|\n|2|19-Jul-2025 01:59:16|68.5900|68.4000|64.2000|70.2100|1019|69|1019|1015|\n|3|19-Jul-2025 03:38:33|65.5000|65.2600|61|67.4400|1019|75|1019|1016|\n|4|19-Jul-2025 04:16:16|64.9400|64.6500|60.3900|67.2800|1019|75|1019|1016|\n|5|19-Jul-2025 04:42:57|64.2200|63.9100|59.3800|66.4500|1019|76|1019|1016|\n|6|19-Jul-2025 04:52:47|63.7500|63.4500|59.2000|66.2900|1019|77|1019|1016|\n|7|19-Jul-2025 05:31:22|62.0100|61.3800|62.0100|62.0100|1020|74|1020|1016|\n|8|19-Jul-2025 05:37:15|62.9200|62.5800|58.1900|65.0800|1020|78|1020|1016|\n|9|19-Jul-2025 05:42:30|62.8500|62.5100|58.1900|65.0800|1020|78|1020|1016|\n|10|19-Jul-2025 06:14:08|62.5800|62.2000|57.7000|64.9400|1019|78|1019|1016|\n|11|19-Jul-2025 06:44:25|61.8800|61.4300|57.2500|64.3500|1020|78|1020|1015|\n|12|19-Jul-2025 06:57:00|61.8800|61.3900|57.1600|64.1100|1019|77|1019|1015|\n|13|19-Jul-2025 07:10:16|61.4800|61.1400|57.2500|63.9500|1019|81|1019|1015|\n|14|19-Jul-2025 07:25:57|61.1400|60.7600|57.2500|63.6600|1019|81|1019|1015|\n\n\nPlot over time\n\n```matlab\nplot(T.time,T.temp,'o-')\nxlabel('time')\nylabel('temperature (F)')\ntitle('Temperature in Boston')\n```\n\n![figure_0.png](README_media/figure_0.png)\n\n## Retime\n```matlab\nTT = table2timetable(T);\n```\n\n![image_1.png](README_media/image_1.png)\n\n```matlab\n% Retime timetable\nTT2 = retime(TT(:,[1 2 3 4]),\"regular\",\"linear\",\"TimeStep\",minutes(10));\n\n% Retime each override variable to same time vector\ntemp2.Vars = [\"pressure\",\"humidity\",\"sea_level\",\"grnd_level\"];\ntemp2.Methods = [\"nearest\",\"nearest\",\"nearest\",\"nearest\"];\ntemp2.Locations = [5 6 7 8];\nfor k = 1:4\n    TT3 = retime(TT(:,temp2.Vars(k)),TT2.Properties.RowTimes, ...\n        temp2.Methods(k));\n    TT2 = addvars(TT2,TT3.(1),'Before',temp2.Locations(k), ...\n        'NewVariableNames',temp2.Vars(k));\nend\nclear temp2 k TT3\n\n% Display results\nTT2\n```\n| |time|temp|feels_like|temp_min|temp_max|pressure|humidity|sea_level|grnd_level|\n|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|\n|1|19-Jul-2025 01:30:00|69.2030|69.0130|65.2670|71.2202|1019|68|1019|1015|\n|2|19-Jul-2025 01:40:00|68.9935|68.8035|64.9024|70.8751|1019|68|1019|1015|\n|3|19-Jul-2025 01:50:00|68.7841|68.5941|64.5378|70.5299|1019|69|1019|1015|\n|4|19-Jul-2025 02:00:00|68.5672|68.3768|64.1764|70.1895|1019|69|1019|1015|\n|5|19-Jul-2025 02:10:00|68.2559|68.0605|63.8541|69.9105|1019|69|1019|1015|\n|6|19-Jul-2025 02:20:00|67.9447|67.7443|63.5317|69.6315|1019|69|1019|1015|\n|7|19-Jul-2025 02:30:00|67.6335|67.4280|63.2094|69.3525|1019|69|1019|1015|\n|8|19-Jul-2025 02:40:00|67.3223|67.1117|62.8871|69.0735|1019|69|1019|1015|\n|9|19-Jul-2025 02:50:00|67.0110|66.7955|62.5648|68.7945|1019|75|1019|1016|\n|10|19-Jul-2025 03:00:00|66.6998|66.4792|62.2425|68.5155|1019|75|1019|1016|\n|11|19-Jul-2025 03:10:00|66.3886|66.1629|61.9202|68.2365|1019|75|1019|1016|\n|12|19-Jul-2025 03:20:00|66.0773|65.8467|61.5979|67.9575|1019|75|1019|1016|\n|13|19-Jul-2025 03:30:00|65.7661|65.5304|61.2756|67.6785|1019|75|1019|1016|\n|14|19-Jul-2025 03:40:00|65.4785|65.2365|60.9765|67.4338|1019|75|1019|1016|\n\n```matlab\nplot(TT2.time,TT2.temp,'o-')\nxlabel('time')\nylabel('temperature (F)')\ntitle('Temperature in Boston')\n```\n\n![figure_1.png](README_media/figure_1.png)\n\n```matlab\nwritetimetable(TT2,\"boston-retimed.csv\")\n```\n\n```matlab\nexport weather_actions.mlx README.md;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslevin48%2Fweather-scraper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslevin48%2Fweather-scraper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslevin48%2Fweather-scraper/lists"}