Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mbeliaev: logging and debugging #287

Merged
merged 2 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ package.
* [FileStat](#filestat)
* [Promote Docker image](#promote-docker-image)
* [Builds](#builds)
* [Logging](#logging)
- [Admin area](#admin-area)
* [User](#user)
+ [API Keys](#api-keys)
Expand Down Expand Up @@ -85,7 +86,6 @@ pip install dohq-artifactory==0.5.dev243
```

# Usage

## Authentication ##

`dohq-artifactory` supports these ways of authentication:
Expand Down Expand Up @@ -505,19 +505,19 @@ You can use [Artifactory Query Language](https://www.jfrog.com/confluence/displa
```python
from artifactory import ArtifactoryPath

aql = ArtifactoryPath(
arti_path = ArtifactoryPath(
"http://my-artifactory/artifactory"
) # path to artifactory, NO repo

# dict support
# Send query:
# items.find({"repo": "myrepo"})
artifacts = aql.aql("items.find", {"repo": "myrepo"})
artifacts = arti_path.aql("items.find", {"repo": "myrepo"})

# list support.
# Send query:
# items.find().include("name", "repo")
artifacts = aql.aql("items.find()", ".include", ["name", "repo"])
artifacts = arti_path.aql("items.find()", ".include", ["name", "repo"])

# support complex query
# Example 1
Expand All @@ -529,7 +529,7 @@ artifacts = aql.aql("items.find()", ".include", ["name", "repo"])
# ]
# }
# )
args = [
aqlargs = [
"items.find",
{
"$and": [
Expand All @@ -546,7 +546,7 @@ args = [

# artifacts_list contains raw data (list of dict)
# Send query
artifacts_list = aql.aql(*args)
artifacts_list = arti_path.aql(*aqlargs)

# Example 2
# The query will find all items in repo docker-prod that are of type file and were created after timecode. The
Expand All @@ -572,11 +572,11 @@ aqlargs = [
".sort",
{"$asc": ["repo", "path", "name"]},
]
artifacts_list = aql.aql(*args)
artifacts_list = arti_path.aql(*aqlargs)

# You can convert to pathlib object:
artifact_pathlib = map(aql.from_aql, artifacts_list)
artifact_pathlib_list = list(map(aql.from_aql, artifacts_list))
artifact_pathlib = map(arti_path.from_aql, artifacts_list)
artifact_pathlib_list = list(map(arti_path.from_aql, artifacts_list))
```


Expand Down Expand Up @@ -651,6 +651,22 @@ build_number1.promote(ci_user="admin", properties={
})
~~~

## Logging
The library can be configured to emit logging that will give you better insight into what it's doing.
Just configure `logging` module in your python script. Simplest example to add debug messages to a console:
~~~python
import logging
from artifactory import ArtifactoryPath

logging.basicConfig()
# set level only for artifactory module, if omitted, then global log level is used, eg from basicConfig
logging.getLogger('artifactory').setLevel(logging.DEBUG)

path = ArtifactoryPath(
"http://my-artifactory/artifactory/myrepo/restricted-path", apikey="MY_API_KEY"
)
~~~

# Admin area
You can manipulate with user\group\repository and permission. First, create `ArtifactoryPath` object without a repository
```python
Expand Down
16 changes: 12 additions & 4 deletions artifactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@
default_config_path = "~/.artifactory_python.cfg"
global_config = None

# set logger to be configurable from external
beliaev-maksim marked this conversation as resolved.
Show resolved Hide resolved
logger = logging.getLogger(__name__)
# Set default logging handler to avoid "No handler found" warnings.
logger.addHandler(logging.NullHandler())


def read_config(config_path=default_config_path):
"""
Expand Down Expand Up @@ -265,7 +270,7 @@ def log_download_progress(bytes_now, total_size):
else:
msg = "Downloaded {}MB".format(int(bytes_now / 1024 / 1024))

logging.debug(msg)
logger.debug(msg)


class HTTPResponseWrapper(object):
Expand Down Expand Up @@ -385,6 +390,7 @@ def quote_url(url):
:param url: (str) URL that should be quoted
:return: (str) quoted URL
"""
logger.debug(f"Raw URL passed for encoding: {url}")
parsed_url = urllib3.util.parse_url(url)
if parsed_url.port:
quoted_path = requests.utils.quote(
Expand Down Expand Up @@ -1332,10 +1338,10 @@ def __new__(cls, *args, **kwargs):
auth_type = kwargs.get("auth_type")

if apikey:
logging.debug("Use XJFrogApiAuth apikey")
logger.debug("Use XJFrogApiAuth apikey")
obj.auth = XJFrogArtApiAuth(apikey=apikey)
elif token:
logging.debug("Use XJFrogArtBearerAuth token")
logger.debug("Use XJFrogArtBearerAuth token")
obj.auth = XJFrogArtBearerAuth(token=token)
else:
auth = kwargs.get("auth")
Expand Down Expand Up @@ -1961,6 +1967,7 @@ def aql(self, *args):
"""
aql_query_url = "{}/api/search/aql".format(self.drive.rstrip("/"))
aql_query_text = self.create_aql_text(*args)
logger.debug(f"AQL query request text: {aql_query_text}")
r = self.session.post(aql_query_url, data=aql_query_text)
r.raise_for_status()
content = r.json()
Expand All @@ -1969,7 +1976,7 @@ def aql(self, *args):
@staticmethod
def create_aql_text(*args):
"""
Create AQL querty from string or list or dict arguments
Create AQL query from string or list or dict arguments
"""
aql_query_text = ""
for arg in args:
Expand All @@ -1978,6 +1985,7 @@ def create_aql_text(*args):
elif isinstance(arg, list):
arg = "({})".format(json.dumps(arg)).replace("[", "").replace("]", "")
aql_query_text += arg

return aql_query_text

def from_aql(self, result):
Expand Down