<commit_before>
import scala.io._
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
import scala.util._

import org.json4s._
import org.json4s.native.JsonMethods._

import scalaj.http._

object GitHubUserAuth {

  implicit val formats = DefaultFormats

  case class User(
    val id:Long,
    val username:String
  )


  def fetchUserFromUrl(url:String):Future[User] = {
    val request = Http(url)
    val token = "" // Your token here
    request.header("Authentication", s"token $token")
    val response = Future { request.asString.body }
    val parsedResponse = response.map { r => parse(r) }
    parsedResponse.flatMap(extractUser)
  }

  def extractUser(jsonResponse:JValue):Future[User] = Future {
    val o = jsonResponse.transformField {
      case ("login", name) => ("username", name)
    }
    o.extract[User]
  }

  def main(args:Array[String]) {
    val names = args.toList
    val users = for {
      name <- names
      url = s"https://api.github.com/users/$name"
      user = fetchUserFromUrl(url)
    } yield user

    names.zip(users).foreach { case(name, user) =>
      user.onComplete {
        case Success(u) => println(s" ** Extracted for $name: $u")
        case Failure(e) => println(s" ** Error fetching user $name: $e")
      }
    }

    Await.ready(Future.sequence(users), 1 minute)

  }

}
<commit_msg>CHAP07: Fetch token from environment.<commit_after>
import scala.io._
import scala.concurrent._
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
import scala.util._

import org.json4s._
import org.json4s.native.JsonMethods._

import scalaj.http._

object GitHubUserAuth {

  implicit val formats = DefaultFormats

  case class User(id:Long, username:String)

  lazy val token:Option[String] = sys.env.get("GHTOKEN") orElse {
    println("No token found: continuing without authentication")
    None
  }

  def fetchUserFromUrl(url:String):Future[User] = {
    val baseRequest = Http(url)
    val request = token match {
      case Some(t) => baseRequest.header("Authentication", s"token $token")
      case None => baseRequest
    }
    val response = Future { request.asString.body }
    val parsedResponse = response.map { r => parse(r) }
    parsedResponse.map { extractUser }
  }

  def extractUser(jsonResponse:JValue):User = {
    val o = jsonResponse.transformField {
      case ("login", name) => ("username", name)
    }
    o.extract[User]
  }

  def main(args:Array[String]) {
    val names = args.toList
    val users = for {
      name <- names
      url = s"https://api.github.com/users/$name"
      user = fetchUserFromUrl(url)
    } yield user

    names.zip(users).foreach { case(name, user) =>
      user.onComplete {
        case Success(u) => println(s" ** Extracted for $name: $u")
        case Failure(e) => println(s" ** Error fetching user $name: $e")
      }
    }

    Await.ready(Future.sequence(users), 1 minute)

  }

}

{'fraction_non_alphanumeric': 0.12521093486331422, 'fraction_numerical': 0.0026999662504218697, 'mean_word_length': 3.1454545454545455, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4500957', 'n_tokens_mistral': 962, 'n_tokens_neox': 935, 'n_words': 223}