{"id":45403965,"url":"https://github.com/herrkaefer/psycopgr","last_synced_at":"2026-02-21T20:41:38.940Z","repository":{"id":50021886,"uuid":"66920604","full_name":"herrkaefer/psycopgr","owner":"herrkaefer","description":"A Python wrapper of pgRouting for routing from nodes to nodes on real map.","archived":false,"fork":false,"pushed_at":"2023-08-14T17:39:37.000Z","size":67,"stargazers_count":28,"open_issues_count":0,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-18T04:38:59.932Z","etag":null,"topics":["astar","dijkstra","openstreetmap","pgrouting","postgis","postgresql","python-wrapper","routing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/herrkaefer.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}},"created_at":"2016-08-30T08:13:09.000Z","updated_at":"2024-09-12T02:03:45.000Z","dependencies_parsed_at":"2023-01-25T06:10:14.809Z","dependency_job_id":null,"html_url":"https://github.com/herrkaefer/psycopgr","commit_stats":{"total_commits":42,"total_committers":4,"mean_commits":10.5,"dds":"0.33333333333333337","last_synced_commit":"449f6aabed0efb94ce4c8989197b06b749825bc6"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/herrkaefer/psycopgr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/herrkaefer%2Fpsycopgr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/herrkaefer%2Fpsycopgr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/herrkaefer%2Fpsycopgr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/herrkaefer%2Fpsycopgr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/herrkaefer","download_url":"https://codeload.github.com/herrkaefer/psycopgr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/herrkaefer%2Fpsycopgr/sbom","scorecard":{"id":462374,"data":{"date":"2025-08-11","repo":{"name":"github.com/herrkaefer/psycopgr","commit":"449f6aabed0efb94ce4c8989197b06b749825bc6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/15 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"15 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2024-230 / GHSA-248v-346w-9cwc","Warn: Project is vulnerable to: PYSEC-2024-60 / GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: PYSEC-2023-117 / GHSA-mrwq-x4v8-fh7p","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2023-74 / GHSA-j8r2-6x86-q33q","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5","Warn: Project is vulnerable to: PYSEC-2022-43012 / GHSA-r9hx-vwmv-q579","Warn: Project is vulnerable to: GHSA-g7vv-2v7x-gj9p","Warn: Project is vulnerable to: GHSA-34jh-p97f-mpxf","Warn: Project is vulnerable to: PYSEC-2023-212 / GHSA-g4mx-q9vg-27p4","Warn: Project is vulnerable to: GHSA-pq67-6m6q-mj2v","Warn: Project is vulnerable to: PYSEC-2023-192 / GHSA-v845-jxx5-vc9f","Warn: Project is vulnerable to: GHSA-jfmj-5v4g-7637"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 16 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T11:28:50.448Z","repository_id":50021886,"created_at":"2025-08-19T11:28:50.448Z","updated_at":"2025-08-19T11:28:50.448Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29692522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T18:18:25.093Z","status":"ssl_error","status_checked_at":"2026-02-21T18:18:22.435Z","response_time":107,"last_error":"SSL_read: 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":["astar","dijkstra","openstreetmap","pgrouting","postgis","postgresql","python-wrapper","routing"],"created_at":"2026-02-21T20:41:34.735Z","updated_at":"2026-02-21T20:41:38.923Z","avatar_url":"https://github.com/herrkaefer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"        ____  _______  ___________  ____  ____ ______\n       / __ \\/ ___/ / / / ___/ __ \\/ __ \\/ __ `/ ___/\n      / /_/ (__  ) /_/ / /__/ /_/ / /_/ / /_/ / /\n     / .___/____/\\__, /\\___/\\____/ .___/\\__, /_/\n    /_/         /____/          /_/    /____/\n\n[![PyPI](https://img.shields.io/pypi/v/psycopgr.svg)](https://pypi.org/project/psycopgr/)\n[![PyPI - License](https://img.shields.io/pypi/l/psycopgr.svg)](https://pypi.org/project/psycopgr/)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/psycopgr.svg)\n\n`psycopgr` is a Python wrapper of [pgRouting](http://pgrouting.org/) with one purpose:\n\n**Computing routes on real map for humans.**\n\nTested with\n\n- Python 3.6.5\n- PostgreSQL 11.2\n- PostGIS 2.5.2\n- pgRouting 2.6.2\n- osm2pgrouting 2.3.6\n\n## Preparation\n\n- Install `PostgreSQL`, `PostGIS`, and `pgRouting`\n- Create database to store map data\n- Import OpenStreet map data into database\n\nA step by step note can be found [here](https://herrkaefer.com/2016/08/30/pgrouting-notes/).\n\n## Installation\n\n```sh\npip install psycopgr\n```\n\nor\n\n```sh\npipenv install psycopgr\n```\n\n## Routing with Python!\n\nFirst, create an PGRouting instance with database connection. Arguments are same as that psycopg2.connect() takes.\n\n```python\nfrom psycopgr import PgrNode, PGRouting\npgr = PGRouting(dbname='mydb', user='user', password='secret',\n                host='localhost', port='5432')\n```\n\nAdjust meta datas of tables including the edge table properies if they are different from the default (only the different properties needs to be set), e.g.:\n\n```python\npgr.set_meta_data(cost='cost_s', reverse_cost='reverse_cost_s', directed=true)\n```\n\nThis is the default meta data:\n\n```python\n{\n    'table': 'ways',\n    'id': 'gid',\n    'source': 'source',\n    'target': 'target',\n    'cost': 'cost_s', # driving time in second\n    'reverse_cost': 'reverse_cost_s', # reverse driving time in second\n    'x1': 'x1',\n    'y1': 'y1',\n    'x2': 'x2',\n    'y2': 'y2',\n    'geometry': 'the_geom',\n    'has_reverse_cost': True,\n    'directed': True,\n    'srid': 4326\n}\n```\n\nNodes are points on map which are represented by `PgrNode` namedtuple with geographic coordinates (longitude and latitude) rather than vague vertex id (vid) in the tables. `PgrNodes` is defined as:\n\n```python\nPgrNode = namedtuple('PgrNode', ['id', 'lon', 'lat'])\n```\n\nin which `id` could be `None` or self-defined value, and `lon` and `lat` are double precision values.\n\nFor example:\n\n```python\nnodes = [PgrNode(None, 116.30150, 40.05500),\n         PgrNode(None, 116.36577, 40.00253),\n         PgrNode(None, 116.30560, 39.95458),\n         PgrNode(None, 116.46806, 39.99857)]\n```\n\nNow we can do routings! This is really straightforward:\n\n```python\n# many-to-many\nroutings = pgr.get_routes(nodes, nodes, end_speed=5.0, pgx_file='r.pgx')\n# one-to-one\nroutings = pgr.get_routes(nodes[0], nodes[1])\n# one-to-many\nroutings = pgr.get_routes(nodes[0], nodes)\n# many-to-one\nroutings = pgr.get_routes(nodes, node[2])\n```\n\n- `end_speed`: speed from node to nearest vertices on ways in unit km/h.\n- `gpx_file`: set it to output paths to a gpx file.\n\nThe returned is a dict of dict: `{(start_node, end_node): {'path': [PgrNode], 'cost': cost}`\n\nBy default, `cost` is traveling time along the path in unit second. It depends on the means of columns of the edge table that you set as `cost` and `reverse_cost`. You can assign the relations by `set_meta_data` function.\n\nWe can also get only costs without detailed paths returned:\n\n```python\ncosts = pgr.get_costs(nodes, nodes)\n```\n\nThe returned is also a dict: `{(start_node, end_node): cost}`\n\n## Low-level wrapper of pgRouting functions\n\n| psycopgr function | pgRouting function |\n| :---------------- | :----------------- |\n| dijkstra          | pgr_dijkstra       |\n| dijkstra_cost     | pgr_dijkstraCost   |\n| astar             | pgr_astar          |\n\nThese are direct wrappings of pgRouting functions. For example, `dijkstra` takes vertex ids as input. This list may be extended in the future.\n\n## Tutorial\n\nHere is a [tutorial](https://herrkaefer.com/2016/09/01/psycopgr-tutorial/).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fherrkaefer%2Fpsycopgr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fherrkaefer%2Fpsycopgr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fherrkaefer%2Fpsycopgr/lists"}