text: import logging
  from json.decoder import JSONDecodeError
  
  import requests
  import yaml
  from .exceptions import GithubRateLimit, MissingResource
  from .github import repos, user, raw
  from ..parsers.project import parse_project
  
  logger = logging.getLogger(__name__)
  
  
  def fetch_public_projects(owner):
      page_size = 100
      repo_count = user(owner)["public_repos"]
  
      return [
          parse_project(repo, fetch_metadata(owner, repo["name"]))
          for page in range(1, repo_count // page_size + 2)
          for repo in fetch_repos(owner, page_size, page)
          if not repo["fork"]
      ]
  
  
  def fetch_repos(owner, page_size, page):
      try:
          return repos(owner, page_size, page)
  
      except (GithubRateLimit, MissingResource) as e:
          logger.info(e)
  
      return []
  
  
  def fetch_metadata(owner, repo):
      try:
          template = yaml.safe_load(raw(owner, repo, "master", ".template.yml"))
  
          if isinstance(template, dict) and "render_context" in template:
              return template["render_context"]
  
      except (yaml.parser.ParserError, GithubRateLimit, MissingResource) as e:
          logger.info(e)
  
      return {}
  