Skip to content

Commit

Permalink
Add readme and documentation for much of the functionality.
Browse files Browse the repository at this point in the history
Closes #3
  • Loading branch information
jaraco committed Sep 10, 2024
1 parent 97c49f3 commit 2822bcb
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Coherent deps (dependencies) is a library of tools used by the [Coherent System](https://bit.ly/coherent-system) for providing insights into the dependencies used by a code base, in particular resolving imports to the dependencies that supply those imports. This sophisticated behavior enables Python projects to avoid the need to declare dependencies and to instead focus on the implementation. The Coherent OSS community provides this library separately to make the functionality available for alternative uses.

See the code documentation for details. See also the [usage in `coherent.build`](https://github.com/coherent-oss/coherent.build/blob/a95e65df11c86658a689a7b7f5f6626321802f7e/discovery.py#L162-L175) for the usage by the build backend.
3 changes: 3 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""
The main event is the :func:`coherent.deps.pypi.distribution_for` function.
"""
21 changes: 20 additions & 1 deletion imports.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
"""
Parse source files and extract the imports in those source files.
Uses static analysis to find all imports (relative and absolute).
Categorizes imports as standard (from the standard library) or
not (third party).
Run this module against a specific file to emit the third-party
imports for that module:
python -m coherent.deps.imports imports.py
"""

from __future__ import annotations

import ast
Expand Down Expand Up @@ -72,7 +86,12 @@ def builtin(self):
@staticmethod
@functools.lru_cache
@CPE.passes
def _check_standard(top_level_name):
def _check_standard(top_level_name: str) -> bool:
"""
Attempt to import the name in a clean Python interpreter.
Return True if it's found in the standard library, and False otherwise.
"""
# Windows can choke without these vars (python/cpython#120836)
safe_isolation = Projection(['SYSTEMDRIVE', 'SYSTEMROOT'], os.environ)
cmd = [sys.executable, '-S', '-c', f'import {top_level_name}']
Expand Down
60 changes: 58 additions & 2 deletions pypi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
"""
Resolve the top-level packages supplied by the most popular distributions.
This functionality is backed by a database hosted in MongoDB Atlas. In
addition to the programmatic APIs provided herein, a MongoDB HTTP
Endpoint is also provided to query the database using a REST API.
Simply issue a GET request to the endpoint URL with a ``root`` parameter
indicating the root import to resolve, and the API will return the
full JSON of the matching database record. For example using
`httpie <https://httpie.io/cli>`_:
http https://us-east-1.aws.data.mongodb-api.com/app/application-0-ponwfin/endpoint/distributions_for root==importlib_metadata
HTTP/1.1 200 OK
content-encoding: gzip
content-length: 155
content-type: application/json
date: Sat, 31 Aug 2024 17:48:55 GMT
server: mdbws
strict-transport-security: max-age=31536000; includeSubdomains;
vary: Origin
x-appservices-request-id: 66d357870823bff37156f0b0
x-frame-options: DENY
x-xgen-up-proto: HTTP/2
{
"_id": "66ba6a7cc4bc876f5a786913",
"downloads": 228476712,
"id": "importlib-metadata",
"name": "importlib_metadata",
"roots": [
"importlib_metadata"
],
"updated": "2024-08-12T20:03:08.919Z"
}
Note the ``id`` member is the
`PEP 503 normalized name <https://peps.python.org/pep-0503/#normalized-names>`_
and the ``name`` is the project's formal name as defined in package metadata.
This API is hosted in a free-tier MongoDB app, which allows for a modest number
of requests, so if using this API, please use it gently or reach out to this project
if the application is likely to generate more than casual use.
"""

import functools
Expand Down Expand Up @@ -90,9 +131,24 @@ def is_root(module):
return client().distributions.find_one({'roots': module})


def distribution_for(import_name):
def distribution_for(import_name: str) -> str:
"""
Resolve a distribution name from an import name.
Resolve a PyPI distribution name from an import name.
>>> distribution_for('pkg_resources')
'setuptools'
>>> distribution_for('cherrypy.lib')
'CherryPy'
>>> distribution_for('backports.configparser')
'configparser'
Raises an exception (StopIteration currently) when no known
distribution presents the name.
>>> distribution_for('import_who_shall_not_be_named.foo.bar')
Traceback (most recent call last):
...
StopIteration...
"""
return next(filter(bool, map(is_root, all_names(import_name))))['name']

Expand Down

0 comments on commit 2822bcb

Please sign in to comment.