> For the complete documentation index, see [llms.txt](https://tk233.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tk233.gitbook.io/notes/tools/python/python-snippets.md).

# Python Snippets

## Logging Utility

<figure><img src="https://1287130752-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FvVJ0h2a4qMIhB1I8GdV8%2Fuploads%2Fgit-blob-b44e8bddd1bbfa90dbe8835d1e19caee5999bf92%2Fimage.png?alt=media" alt=""><figcaption></figcaption></figure>

### Logging Formats

```bash
2024-04-10 15:02:51 [Info] <Main> Starting up...
2024-04-10 15:02:51 [ERROR] <Module-A> Error doing something
```

## Converting Between JSON and XML

```bash
pip install cc-xmljson
```

```python
import xml
import json
from cc.xmljson import XMLJSON

def xml2json(in_file):
    xml_data = ""
    with open(in_file, "r") as f:
        xml_data = f.read()

    json_data = XMLJSON.gdata.data(xml.etree.ElementTree.fromstring(xml_data))
    return json_data
    
def json2xml(in_file):
    json_data = json.load(open(in_file, "r"))
    
    xml_data = XMLJSON.gdata.etree(json_data, root=xml.etree.ElementTree.Element("root"))
    xml_data = xml.etree.ElementTree.tostring(xml_data, encoding="utf8")
    return xml_data

print(xml2json("tests/abdera-1.xml"))
print(json2xml("tests/abdera-1.json"))


```

## Retrieve GitHub User Avatars

```python
import time

import requests

headers = {
    "Authorization": "Bearer GITHUB_OAUTH_KEY"
    }


fetched_names = []

for i in range(100):
    print("="*16)
    print(i)
    print("="*16)
    resp = requests.get("https://api.github.com/repos/ucb-bar/chipyard/commits?per_page=100&page={page}".format(page=i), headers=headers)
    commits = resp.json()

    time.sleep(0.1)
    if not commits:
        break

    for commit in commits:
        author = commit.get("author")
        if not author:
            continue
        
        username = author.get("login")
        name = commit.get("commit").get("author").get("name")

        print(username, "-", name)
        if name in fetched_names:
            continue
        print("  downloading...")

        r = requests.get("https://github.com/{username}.png?size=90".format(username=username), headers=headers, allow_redirects=True)
        open(".git\\avatar\\{name}.png".format(name=name), "wb").write(r.content)
        fetched_names.append(name)

        time.sleep(0.1)

print("finished")

```

```python
#!/usr/bin/env python3
# fetch Gravatars

import hashlib
import os
import requests
from subprocess import Popen, PIPE
import time

size = 90
output_dir = ".git/avatar"

if not os.path.isdir(".git"):
    raise FileNotFoundError("no .git/ directory found in current path")

if not os.path.isdir(output_dir):
    os.makedirs(output_dir)

git_log_process = Popen(["git", "log", "--pretty=format:%ae|%an"], stdout=PIPE, text=True)
git_log_output = git_log_process.communicate()[0]

processed_authors = set()

for line in git_log_output.splitlines():
    email, author = line.strip().split("|")

    if author in processed_authors:
        continue

    processed_authors.add(author)

    author_image_file = os.path.join(output_dir, f"{author}.png")

    # skip images we have
    if os.path.exists(author_image_file):
        continue

    # try and fetch image
    md5_hash = hashlib.md5(email.lower().encode()).hexdigest()
    grav_url = f"http://www.gravatar.com/avatar/{md5_hash}?d=404&size={size}"

    print(f"fetching image for '{author}' {email} ({grav_url})...")

    response = requests.get(grav_url, stream=True)

    if response.status_code == 200:
        with open(author_image_file, "wb") as f:
            for chunk in response.iter_content(1024):
                f.write(chunk)
        response.close()
    else:
        print("error:", response.status_code)
        response.close()
        continue

    # sleep to avoid hitting Gravatar API too hard
    time.sleep(1)

```

## Jupyter Notebook Error

```bash
Failed to load model class 'MPLCanvasModel' from module 'jupyter-matplotlib'
```

Fix:

```bash
jupyter nbextension enable --py widgetsnbextension
```
