# Project export: Refact

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: Cal Hacks 11.0
- Tagline: FactAI is a browser extension that instantly fact-checks articles while you browse. Powered by Perpexity AI's API, it verifies claims and summarizes content, providing reliable insights in real time.
- Devpost: https://devpost.com/software/refact
- GitHub: https://github.com/hirdey795/FactCheckAI
- Team: 4 GitHub contributor(s) — Prithvi-Maddi (9 commits), hirdey795 (5 commits), Sumaiya (3 commits), Nitop70 (2 commits)

## Devpost submission (written by the team)

### Inspiration

We wanted to create an easy way for users to fact-check news articles directly within their browser. With the rise of misinformation, Refact aims to provide a tool for quick, accessible fact-checking.

### What it does

Refact allows users to input an article's text, and it verifies the information using the Perplexity API. It delivers fact-check results in real-time through a user-friendly interface, helping users verify claims easily.

### How we built it

The project uses a Flask backend to connect with the Perplexity API, which performs the fact-checking. We built the frontend using HTML, CSS, and JavaScript, designed for a smooth experience inside a browser extension. The extension communicates with the backend to process requests and display the results.

### Challenges we ran into

We had some struggles in connecting the Flask backend to the frontend, particularly in setting up a reliable flow of information between the browser extension and the server. Ensuring seamless communication was crucial to avoid delays in fact-checking.

### Accomplishments we're proud of

We successfully integrated a functional fact-checking system using the Perplexity API. The browser extension works smoothly, and we’ve achieved a user-friendly interface.

### What we learned

We learned the complexities of building a backend that interfaces with browser extensions, especially regarding API integration and managing cross-domain communication between the frontend and backend.

### What's next

We plan to expand Refact by integrating additional APIs for more comprehensive fact-checking. We’re also exploring adding other tools like article summarization to further enhance the user experience.

## README (from the GitHub repository)

# FactCheckAI

Overview
Fact Checker AI is a tool designed to verify the accuracy of written statements in articles and reports. The AI scans articles, checks the factual accuracy of key claims, and provides a summary of how truthful the content is. It is aimed at offering quick and reliable fact-checking for articles, making it easier to discern credible information from misleading content.

This version focuses solely on article fact-checking due to time constraints, with plans for future expansion to video-based fact-checking.

Our project addresses a critical need in today's information landscape: helping people make more informed decisions, particularly during high-stakes events like presidential elections. In an age where political discourse is often flooded with misinformation, our solution empowers voters to access accurate, unbiased information in real-time. By providing instant fact-checking during debates and political speeches, we aim to reduce the influence of misleading or false statements, allowing the electorate to focus on the actual issues at hand.

Our system integrates natural language processing (NLP) with advanced AI-driven fact-checking algorithms. It begins by analyzing live or pre-recorded YouTube videos of debates or speeches. Using the YouTube API, our application extracts video transcriptions and processes them through spaCy, a robust NLP library, to identify key claims and statements. These are then cross-referenced with fact-checking databases through our AI agent to determine their accuracy. The result is an easily accessible, real-time report on whether a statement is factually true, incorrect, or an opinion.

From a technical perspective, our project employs a variety of cutting-edge tools. We use Python as the core programming language, integrating with the YouTube API for transcription extraction and spaCy for linguistic processing. This combination allows our system to accurately extract and evaluate sentences from complex speech patterns. On the front end, we developed a browser extension using JavaScript and background.js to automatically provide fact-checking feedback as users browse YouTube videos or articles. This seamless integration enables users to view content without needing to manually input links.

Additionally, by leveraging pre-trained models and sophisticated algorithms, our system achieves real-time fact-checking without the need for extensive re-training, making it both scalable and efficient. This project highlights the power of NLP, AI, and real-world data integration, resulting in a technically complex yet user-friendly solution for promoting informed voting in presidential elections.


## Detected evidence (automated analysis)

Indexed codebase: 2092 recognized source files, 21086 KB.
- C (language) — detected in the code
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- Python (language) — detected in the code
- Flask (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (120 of 2669)

```
.DS_Store
article.json
backend/.DS_Store
backend/agent.py
backend/agent2.py
backend/fetchai-env/bin/activate
backend/fetchai-env/bin/activate.csh
backend/fetchai-env/bin/activate.fish
backend/fetchai-env/bin/Activate.ps1
backend/fetchai-env/bin/flask
backend/fetchai-env/bin/jsonschema
backend/fetchai-env/bin/normalizer
backend/fetchai-env/bin/pip
backend/fetchai-env/bin/pip 2
backend/fetchai-env/bin/pip3
backend/fetchai-env/bin/pip3 2
backend/fetchai-env/bin/pip3.11
backend/fetchai-env/bin/pip3.11 2
backend/fetchai-env/bin/python
backend/fetchai-env/bin/python3
backend/fetchai-env/bin/python3.11
backend/fetchai-env/bin/uvicorn
backend/fetchai-env/lib/python3.11/site-packages/_distutils_hack/__init__.py
backend/fetchai-env/lib/python3.11/site-packages/_distutils_hack/override.py
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs-2.4.3.dist-info/INSTALLER
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs-2.4.3.dist-info/LICENSE
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs-2.4.3.dist-info/METADATA
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs-2.4.3.dist-info/RECORD
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs-2.4.3.dist-info/WHEEL
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/__init__.py
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/_staggered.py
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/impl.py
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/py.typed
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/types.py
backend/fetchai-env/lib/python3.11/site-packages/aiohappyeyeballs/utils.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/INSTALLER
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/LICENSE.txt
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/METADATA
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/RECORD
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/top_level.txt
backend/fetchai-env/lib/python3.11/site-packages/aiohttp-3.10.10.dist-info/WHEEL
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/__init__.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_cparser.pxd
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_find_header.pxd
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_headers.pxi
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_helpers.pyi
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_helpers.pyx
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_http_parser.pyx
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_http_writer.pyx
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/_websocket.pyx
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_cparser.pxd.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_find_header.pxd.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_helpers.pyi.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_helpers.pyx.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_http_parser.pyx.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_http_writer.pyx.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/_websocket.pyx.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/.hash/hdrs.py.hash
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/abc.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/base_protocol.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/client_exceptions.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/client_proto.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/client_reqrep.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/client_ws.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/client.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/compression_utils.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/connector.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/cookiejar.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/formdata.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/hdrs.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/helpers.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/http_exceptions.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/http_parser.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/http_websocket.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/http_writer.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/http.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/log.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/multipart.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/payload_streamer.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/payload.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/py.typed
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/pytest_plugin.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/resolver.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/streams.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/tcp_helpers.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/test_utils.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/tracing.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/typedefs.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_app.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_exceptions.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_fileresponse.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_log.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_middlewares.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_protocol.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_request.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_response.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_routedef.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_runner.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_server.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_urldispatcher.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web_ws.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/web.py
backend/fetchai-env/lib/python3.11/site-packages/aiohttp/worker.py
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/INSTALLER
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/LICENSE
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/METADATA
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/RECORD
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/top_level.txt
backend/fetchai-env/lib/python3.11/site-packages/aiosignal-1.3.1.dist-info/WHEEL
backend/fetchai-env/lib/python3.11/site-packages/aiosignal/__init__.py
backend/fetchai-env/lib/python3.11/site-packages/aiosignal/__init__.pyi
backend/fetchai-env/lib/python3.11/site-packages/aiosignal/py.typed
backend/fetchai-env/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/INSTALLER
backend/fetchai-env/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/licenses/LICENSE
backend/fetchai-env/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/METADATA
backend/fetchai-env/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/RECORD
backend/fetchai-env/lib/python3.11/site-packages/annotated_types-0.7.0.dist-info/WHEEL
backend/fetchai-env/lib/python3.11/site-packages/annotated_types/__init__.py
backend/fetchai-env/lib/python3.11/site-packages/annotated_types/py.typed
backend/fetchai-env/lib/python3.11/site-packages/annotated_types/test_cases.py
[2549 more files omitted for size]
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- Bigger Disclaimer Font
- Demo Commit
- Update README.md
- Update README.md
- Merge branch 'main' of https://github.com/hirdey795/FactCheckAI
- upgrade backend.py
- Disclaimer added
- upgrades
- Updated Frontend
- Updated Frontend
- Merge branch 'main' of https://github.com/hirdey795/FactCheckAI
- Merge branch 'main' into sumaiyaV2
- backend.py
- Add agent2.py for summarization feature
- Agent.py adjustment to work with Perplexity
- init commit
- Updated Agent Logic (WIP)
- started extension
- added the backend
- Add files via upload

## Key source files (fetched from GitHub, selected and truncated for size)

### backend/fetchai-env/lib/python3.11/site-packages/idna-3.10.dist-info/LICENSE.md

```markdown
BSD 3-Clause License

Copyright (c) 2013-2024, Kim Davies and contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

```

### backend/fetchai-env/lib/python3.11/site-packages/uvicorn-0.30.6.dist-info/licenses/LICENSE.md

```markdown
Copyright © 2017-present, [Encode OSS Ltd](https://www.encode.io/).
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

```

### backend/package.json

```
{
  "name": "calhacks",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

```

### backend/fetchai-env/lib/python3.11/site-packages/jsonschema/cli.py

```python
"""
The ``jsonschema`` command line.
"""

from importlib import metadata
from json import JSONDecodeError
from textwrap import dedent
import argparse
import json
import sys
import traceback
import warnings

try:
    from pkgutil import resolve_name
except ImportError:
    from pkgutil_resolve_name import resolve_name  # type: ignore[no-redef]

from attrs import define, field

from jsonschema.exceptions import SchemaError
from jsonschema.validators import _RefResolver, validator_for

warnings.warn(
    (
        "The jsonschema CLI is deprecated and will be removed in a future "
        "version. Please use check-jsonschema instead, which can be installed "
        "from https://pypi.org/project/check-jsonschema/"
    ),
    DeprecationWarning,
    stacklevel=2,
)


class _CannotLoadFile(Exception):
    pass


@define
class _Outputter:

    _formatter = field()
    _stdout = field()
    _stderr = field()

    @classmethod
    def from_arguments(cls, arguments, stdout, stderr):
        if arguments["output"] == "plain":
            formatter = _PlainFormatter(arguments["error_format"])
        elif arguments["output"] == "pretty":
            formatter = _PrettyFormatter()
        return cls(formatter=formatter, stdout=stdout, stderr=stderr)

    def load(self, path):
        try:
            file = open(path)  # noqa: SIM115, PTH123
        except FileNotFoundError as error:
            self.filenotfound_error(path=path, exc_info=sys.exc_info())
            raise _CannotLoadFile() from error

        with file:
            try:
                return json.load(file)
            except JSONDecodeError as error:
                self.parsing_error(path=path, exc_info=sys.exc_info())
                raise _CannotLoadFile() from error

    def filenotfound_error(self, **kwargs):
        self._stderr.write(self._formatter.filenotfound_error(**kwargs))

    def parsing_error(self, **kwargs):
        self._stderr.write(self._formatter.parsing_error(**kwargs))

    def validation_error(self, **kwargs):
        self._stderr.write(self._formatter.validation_error(**kwargs))

    def validation_success(self, **kwargs):
        self._stdout.write(self._formatter.validation_success(**kwargs))


@define
class _PrettyFormatter:

    _ERROR_MSG = dedent(
        """\
        ===[{type}]===({path})===

        {body}
        -----------------------------
        """,
    )
    _SUCCESS_MSG = "===[SUCCESS]===({path})===\n"

    def filenotfound_error(self, path, exc_info):
        return self._ERROR_MSG.format(
            path=path,
            type="FileNotFoundError",
            body=f"{path!r} does not exist.",
        )

    def parsing_error(self, path, exc_info):
        exc_type, exc_value, exc_traceback = exc_info
        exc_lines = "".join(
            traceback.format_exception(exc_type, exc_value, exc_traceback),
        )
        return self._ERROR_MSG.format(
            path=path,
            type=exc_type.__name__,
            body=exc_lines,
        )

    def validation_error(self, instance_path, error):
        return self._ERROR_MSG.format(
            path=instance_path,
            type=error.__class__.__name__,
            body=error,
        )

    def validation_success(self, instance_path):
        return self._SUCCESS_MSG.format(path=instance_path)


@define
class _PlainFormatter:

    _error_format = field()

    def filenotfound_error(self, path, exc_info):
        return f"{path!r} does not exist.\n"

    def parsing_error(self, path, exc_info):
        return "Failed to parse {}: {}\n".format(
            "<stdin>" if path == "<stdin>" else repr(path),
            exc_info[1],
        )

    def validation_error(self, instance_path, error):
        return self._error_format.format(file_name=instance_path, error=error)

    def validation_success(self, instance_path):
        return ""


def _resolve_name_with_default(name):
    if "." not in name:
        name = "jsonschema." + name
    return resolve_name(name)


parser = argparse.ArgumentParser(
    description="JSON Schema Validation CLI",
)
parser.add_argument(
    "-i", "--instance",
    action="append",
    dest="instances",
    help="""
        a path to a JSON instance (i.e. filename.json) to validate (may
        be specified multiple times). If no instances are provided via this
        option, one will be expected on standard input.
    """,
)
parser.add_argument(
    "-F", "--error-format",
    help="""
        the format to use for each validation error message, specified
        in a form suitable for str.format. This string will be passed
        one formatted object named 'error' for each ValidationError.
        Only provide this option when using --output=plain, which is the
        default. If this argument is unprovided and --output=plain is
        used, a simple default representation will be used.
    """,
)
parser.add_argument(
    "-o", "--output",
    choices=["plain", "pretty"],
    default="plain",
    help="""
        an output format to use. 'plain' (default) will produce minimal
        text with one line for each error, while 'pretty' will produce
        more detailed human-readable output on multiple lines.
    """,
)
parser.add_argument(
    "-V", "--validator",
    type=_resolve_name_with_default,
    help="""
        the fully qualified object name of a validator to use, or, for
        validators that are registered with jsonschema, simply the name
        of the class.
    """,
)
parser.add_argument(
    "--base-uri",
    help="""
        a base URI to assign to the provided schema, even if it does not
        declare one (via e.g. $id). This option can be used if you wish to
        resolve relative references to a particular URI (or local path)
    """,
)
parser.add_argument(
    "--version",
    action="version",
    version=metadata.version("jsonschema"),
)
parser.add_argument(
    "schema",
    help="the path to a JSON Schema to validate with (i.e. schema.json)",
)


def parse_args
[truncated — 2551 more characters]
```

### backend/fetchai-env/lib/python3.11/site-packages/uvicorn/server.py

```python
from __future__ import annotations

import asyncio
import contextlib
import logging
import os
import platform
import signal
import socket
import sys
import threading
import time
from email.utils import formatdate
from types import FrameType
from typing import TYPE_CHECKING, Generator, Sequence, Union

import click

from uvicorn.config import Config

if TYPE_CHECKING:
    from uvicorn.protocols.http.h11_impl import H11Protocol
    from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol
    from uvicorn.protocols.websockets.websockets_impl import WebSocketProtocol
    from uvicorn.protocols.websockets.wsproto_impl import WSProtocol

    Protocols = Union[H11Protocol, HttpToolsProtocol, WSProtocol, WebSocketProtocol]

HANDLED_SIGNALS = (
    signal.SIGINT,  # Unix signal 2. Sent by Ctrl+C.
    signal.SIGTERM,  # Unix signal 15. Sent by `kill <pid>`.
)
if sys.platform == "win32":  # pragma: py-not-win32
    HANDLED_SIGNALS += (signal.SIGBREAK,)  # Windows signal 21. Sent by Ctrl+Break.

logger = logging.getLogger("uvicorn.error")


class ServerState:
    """
    Shared servers state that is available between all protocol instances.
    """

    def __init__(self) -> None:
        self.total_requests = 0
        self.connections: set[Protocols] = set()
        self.tasks: set[asyncio.Task[None]] = set()
        self.default_headers: list[tuple[bytes, bytes]] = []


class Server:
    def __init__(self, config: Config) -> None:
        self.config = config
        self.server_state = ServerState()

        self.started = False
        self.should_exit = False
        self.force_exit = False
        self.last_notified = 0.0

        self._captured_signals: list[int] = []

    def run(self, sockets: list[socket.socket] | None = None) -> None:
        self.config.setup_event_loop()
        return asyncio.run(self.serve(sockets=sockets))

    async def serve(self, sockets: list[socket.socket] | None = None) -> None:
        with self.capture_signals():
            await self._serve(sockets)

    async def _serve(self, sockets: list[socket.socket] | None = None) -> None:
        process_id = os.getpid()

        config = self.config
        if not config.loaded:
            config.load()

        self.lifespan = config.lifespan_class(config)

        message = "Started server process [%d]"
        color_message = "Started server process [" + click.style("%d", fg="cyan") + "]"
        logger.info(message, process_id, extra={"color_message": color_message})

        await self.startup(sockets=sockets)
        if self.should_exit:
            return
        await self.main_loop()
        await self.shutdown(sockets=sockets)

        message = "Finished server process [%d]"
        color_message = "Finished server process [" + click.style("%d", fg="cyan") + "]"
        logger.info(message, process_id, extra={"color_message": color_message})

    async def startup(self, sockets: list[socket.socket] | None = None) -> None:
        await self.lifespan.startup()
        if self.lifespan.should_exit:
            self.should_exit = True
            return

        config = self.config

        def create_protocol(
            _loop: asyncio.AbstractEventLoop | None = None,
        ) -> asyncio.Protocol:
            return config.http_protocol_class(  # type: ignore[call-arg]
                config=config,
                server_state=self.server_state,
                app_state=self.lifespan.state,
                _loop=_loop,
            )

        loop = asyncio.get_running_loop()

        listeners: Sequence[socket.SocketType]
        if sockets is not None:  # pragma: full coverage
            # Explicitly passed a list of open sockets.
            # We use this when the server is run from a Gunicorn worker.

            def _share_socket(
                sock: socket.SocketType,
            ) -> socket.SocketType:  # pragma py-linux pragma: py-darwin
                # Windows requires the socket be explicitly shared across
                # multiple workers (processes).
                from socket import fromshare  # type: ignore[attr-defined]

                sock_data = sock.share(os.getpid())  # type: ignore[attr-defined]
                return fromshare(sock_data)

            self.servers: list[asyncio.base_events.Server] = []
            for sock in sockets:
                is_windows = platform.system() == "Windows"
                if config.workers > 1 and is_windows:  # pragma: py-not-win32
                    sock = _share_socket(sock)  # type: ignore[assignment]
                server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog)
                self.servers.append(server)
            listeners = sockets

        elif config.fd is not None:  # pragma: py-win32
            # Use an existing socket, from a file descriptor.
            sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM)
            server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog)
            assert server.sockets is not None  # mypy
            listeners = server.sockets
            self.servers = [server]

        elif config.uds is not None:  # pragma: py-win32
            # Create a socket using UNIX domain socket.
            uds_perms = 0o666
            if os.path.exists(config.uds):
                uds_perms = os.stat(config.uds).st_mode  # pragma: full coverage
            server = await loop.create_unix_server(
                create_protocol, path=config.uds, ssl=config.ssl, backlog=config.backlog
            )
            os.chmod(config.uds, uds_perms)
            assert server.sockets is not None  # mypy
            listeners = server.sockets
            self.servers = [server]

        else:
            # Standard case. Create a socket from a host/port pair.
            try:
                server = await loop.create_server(
                    create_protocol,
                    host=co
[truncated — 6879 more characters]
```

### backend/fetchai-env/lib/python3.11/site-packages/uvicorn/main.py

```python
from __future__ import annotations

import asyncio
import logging
import os
import platform
import ssl
import sys
from configparser import RawConfigParser
from typing import IO, Any, Callable

import click

import uvicorn
from uvicorn._types import ASGIApplication
from uvicorn.config import (
    HTTP_PROTOCOLS,
    INTERFACES,
    LIFESPAN,
    LOG_LEVELS,
    LOGGING_CONFIG,
    LOOP_SETUPS,
    SSL_PROTOCOL_VERSION,
    WS_PROTOCOLS,
    Config,
    HTTPProtocolType,
    InterfaceType,
    LifespanType,
    LoopSetupType,
    WSProtocolType,
)
from uvicorn.server import Server, ServerState  # noqa: F401  # Used to be defined here.
from uvicorn.supervisors import ChangeReload, Multiprocess

LEVEL_CHOICES = click.Choice(list(LOG_LEVELS.keys()))
HTTP_CHOICES = click.Choice(list(HTTP_PROTOCOLS.keys()))
WS_CHOICES = click.Choice(list(WS_PROTOCOLS.keys()))
LIFESPAN_CHOICES = click.Choice(list(LIFESPAN.keys()))
LOOP_CHOICES = click.Choice([key for key in LOOP_SETUPS.keys() if key != "none"])
INTERFACE_CHOICES = click.Choice(INTERFACES)

STARTUP_FAILURE = 3

logger = logging.getLogger("uvicorn.error")


def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> None:
    if not value or ctx.resilient_parsing:
        return
    click.echo(
        "Running uvicorn {version} with {py_implementation} {py_version} on {system}".format(  # noqa: UP032
            version=uvicorn.__version__,
            py_implementation=platform.python_implementation(),
            py_version=platform.python_version(),
            system=platform.system(),
        )
    )
    ctx.exit()


@click.command(context_settings={"auto_envvar_prefix": "UVICORN"})
@click.argument("app", envvar="UVICORN_APP")
@click.option(
    "--host",
    type=str,
    default="127.0.0.1",
    help="Bind socket to this host.",
    show_default=True,
)
@click.option(
    "--port",
    type=int,
    default=8000,
    help="Bind socket to this port. If 0, an available port will be picked.",
    show_default=True,
)
@click.option("--uds", type=str, default=None, help="Bind to a UNIX domain socket.")
@click.option("--fd", type=int, default=None, help="Bind to socket from this file descriptor.")
@click.option("--reload", is_flag=True, default=False, help="Enable auto-reload.")
@click.option(
    "--reload-dir",
    "reload_dirs",
    multiple=True,
    help="Set reload directories explicitly, instead of using the current working" " directory.",
    type=click.Path(exists=True),
)
@click.option(
    "--reload-include",
    "reload_includes",
    multiple=True,
    help="Set glob patterns to include while watching for files. Includes '*.py' "
    "by default; these defaults can be overridden with `--reload-exclude`. "
    "This option has no effect unless watchfiles is installed.",
)
@click.option(
    "--reload-exclude",
    "reload_excludes",
    multiple=True,
    help="Set glob patterns to exclude while watching for files. Includes "
    "'.*, .py[cod], .sw.*, ~*' by default; these defaults can be overridden "
    "with `--reload-include`. This option has no effect unless watchfiles is "
    "installed.",
)
@click.option(
    "--reload-delay",
    type=float,
    default=0.25,
    show_default=True,
    help="Delay between previous and next check if application needs to be." " Defaults to 0.25s.",
)
@click.option(
    "--workers",
    default=None,
    type=int,
    help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment"
    " variable if available, or 1. Not valid with --reload.",
)
@click.option(
    "--loop",
    type=LOOP_CHOICES,
    default="auto",
    help="Event loop implementation.",
    show_default=True,
)
@click.option(
    "--http",
    type=HTTP_CHOICES,
    default="auto",
    help="HTTP protocol implementation.",
    show_default=True,
)
@click.option(
    "--ws",
    type=WS_CHOICES,
    default="auto",
    help="WebSocket protocol implementation.",
    show_default=True,
)
@click.option(
    "--ws-max-size",
    type=int,
    default=16777216,
    help="WebSocket max size message in bytes",
    show_default=True,
)
@click.option(
    "--ws-max-queue",
    type=int,
    default=32,
    help="The maximum length of the WebSocket message queue.",
    show_default=True,
)
@click.option(
    "--ws-ping-interval",
    type=float,
    default=20.0,
    help="WebSocket ping interval in seconds.",
    show_default=True,
)
@click.option(
    "--ws-ping-timeout",
    type=float,
    default=20.0,
    help="WebSocket ping timeout in seconds.",
    show_default=True,
)
@click.option(
    "--ws-per-message-deflate",
    type=bool,
    default=True,
    help="WebSocket per-message-deflate compression",
    show_default=True,
)
@click.option(
    "--lifespan",
    type=LIFESPAN_CHOICES,
    default="auto",
    help="Lifespan implementation.",
    show_default=True,
)
@click.option(
    "--interface",
    type=INTERFACE_CHOICES,
    default="auto",
    help="Select ASGI3, ASGI2, or WSGI as the application interface.",
    show_default=True,
)
@click.option(
    "--env-file",
    type=click.Path(exists=True),
    default=None,
    help="Environment configuration file.",
    show_default=True,
)
@click.option(
    "--log-config",
    type=click.Path(exists=True),
    default=None,
    help="Logging configuration file. Supported formats: .ini, .json, .yaml.",
    show_default=True,
)
@click.option(
    "--log-level",
    type=LEVEL_CHOICES,
    default=None,
    help="Log level. [default: info]",
    show_default=True,
)
@click.option(
    "--access-log/--no-access-log",
    is_flag=True,
    default=True,
    help="Enable/Disable access log.",
)
@click.option(
    "--use-colors/--no-use-colors",
    is_flag=True,
    default=None,
    help="Enable/Disable colorized logging.",
)
@click.option(
    "--proxy-headers/--no-proxy-headers",
    is_flag=True,
    default=True,
    help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For, X-Forwarded-Port to " "populate remote address info.",
)
@click.option(
 
[truncated — 10783 more characters]
```

### backend/fetchai-env/lib/python3.11/site-packages/websockets/server.py

```python
from __future__ import annotations

import base64
import binascii
import email.utils
import http
from typing import Generator, List, Optional, Sequence, Tuple, cast

from .connection import CONNECTING, OPEN, SERVER, Connection, State
from .datastructures import Headers, MultipleValuesError
from .exceptions import (
    InvalidHandshake,
    InvalidHeader,
    InvalidHeaderValue,
    InvalidOrigin,
    InvalidStatus,
    InvalidUpgrade,
    NegotiationError,
)
from .extensions import Extension, ServerExtensionFactory
from .headers import (
    build_extension,
    parse_connection,
    parse_extension,
    parse_subprotocol,
    parse_upgrade,
)
from .http11 import Request, Response
from .typing import (
    ConnectionOption,
    ExtensionHeader,
    LoggerLike,
    Origin,
    Subprotocol,
    UpgradeProtocol,
)
from .utils import accept_key


# See #940 for why lazy_import isn't used here for backwards compatibility.
from .legacy.server import *  # isort:skip  # noqa


__all__ = ["ServerConnection"]


class ServerConnection(Connection):
    """
    Sans-I/O implementation of a WebSocket server connection.

    Args:
        origins: acceptable values of the ``Origin`` header; include
            :obj:`None` in the list if the lack of an origin is acceptable.
            This is useful for defending against Cross-Site WebSocket
            Hijacking attacks.
        extensions: list of supported extensions, in order in which they
            should be tried.
        subprotocols: list of supported subprotocols, in order of decreasing
            preference.
        state: initial state of the WebSocket connection.
        max_size: maximum size of incoming messages in bytes;
            :obj:`None` to disable the limit.
        logger: logger for this connection;
            defaults to ``logging.getLogger("websockets.client")``;
            see the :doc:`logging guide <../topics/logging>` for details.

    """

    def __init__(
        self,
        origins: Optional[Sequence[Optional[Origin]]] = None,
        extensions: Optional[Sequence[ServerExtensionFactory]] = None,
        subprotocols: Optional[Sequence[Subprotocol]] = None,
        state: State = CONNECTING,
        max_size: Optional[int] = 2**20,
        logger: Optional[LoggerLike] = None,
    ):
        super().__init__(
            side=SERVER,
            state=state,
            max_size=max_size,
            logger=logger,
        )
        self.origins = origins
        self.available_extensions = extensions
        self.available_subprotocols = subprotocols

    def accept(self, request: Request) -> Response:
        """
        Create a handshake response to accept the connection.

        If the connection cannot be established, the handshake response
        actually rejects the handshake.

        You must send the handshake response with :meth:`send_response`.

        You can modify it before sending it, for example to add HTTP headers.

        Args:
            request: WebSocket handshake request event received from the client.

        Returns:
            Response: WebSocket handshake response event to send to the client.

        """
        try:
            (
                accept_header,
                extensions_header,
                protocol_header,
            ) = self.process_request(request)
        except InvalidOrigin as exc:
            request._exception = exc
            self.handshake_exc = exc
            if self.debug:
                self.logger.debug("! invalid origin", exc_info=True)
            return self.reject(
                http.HTTPStatus.FORBIDDEN,
                f"Failed to open a WebSocket connection: {exc}.\n",
            )
        except InvalidUpgrade as exc:
            request._exception = exc
            self.handshake_exc = exc
            if self.debug:
                self.logger.debug("! invalid upgrade", exc_info=True)
            response = self.reject(
                http.HTTPStatus.UPGRADE_REQUIRED,
                (
                    f"Failed to open a WebSocket connection: {exc}.\n"
                    f"\n"
                    f"You cannot access a WebSocket server directly "
                    f"with a browser. You need a WebSocket client.\n"
                ),
            )
            response.headers["Upgrade"] = "websocket"
            return response
        except InvalidHandshake as exc:
            request._exception = exc
            self.handshake_exc = exc
            if self.debug:
                self.logger.debug("! invalid handshake", exc_info=True)
            return self.reject(
                http.HTTPStatus.BAD_REQUEST,
                f"Failed to open a WebSocket connection: {exc}.\n",
            )
        except Exception as exc:
            request._exception = exc
            self.handshake_exc = exc
            self.logger.error("opening handshake failed", exc_info=True)
            return self.reject(
                http.HTTPStatus.INTERNAL_SERVER_ERROR,
                (
                    "Failed to open a WebSocket connection.\n"
                    "See server log for more information.\n"
                ),
            )

        headers = Headers()

        headers["Date"] = email.utils.formatdate(usegmt=True)

        headers["Upgrade"] = "websocket"
        headers["Connection"] = "Upgrade"
        headers["Sec-WebSocket-Accept"] = accept_header

        if extensions_header is not None:
            headers["Sec-WebSocket-Extensions"] = extensions_header

        if protocol_header is not None:
            headers["Sec-WebSocket-Protocol"] = protocol_header

        self.logger.info("connection open")
        return Response(101, "Switching Protocols", headers)

    def process_request(
        self, request: Request
    ) -> Tuple[str, Optional[str], Optional[str]]:
        """
        Check a handshake request and negotiate extensions and subprotocol.

        This function doesn't verify that the request is an 
[truncated — 12480 more characters]
```

### backend/fetchai-env/lib/python3.11/site-packages/pip/_internal/main.py

```python
from typing import List, Optional


def main(args: Optional[List[str]] = None) -> int:
    """This is preserved for old console scripts that may still be referencing
    it.

    For additional details, see https://github.com/pypa/pip/issues/7498.
    """
    from pip._internal.utils.entrypoints import _wrapper

    return _wrapper(args)

```

### backend/fetchai-env/lib/python3.11/site-packages/flask/cli.py

```python
from __future__ import annotations

import ast
import collections.abc as cabc
import importlib.metadata
import inspect
import os
import platform
import re
import sys
import traceback
import typing as t
from functools import update_wrapper
from operator import itemgetter
from types import ModuleType

import click
from click.core import ParameterSource
from werkzeug import run_simple
from werkzeug.serving import is_running_from_reloader
from werkzeug.utils import import_string

from .globals import current_app
from .helpers import get_debug_flag
from .helpers import get_load_dotenv

if t.TYPE_CHECKING:
    import ssl

    from _typeshed.wsgi import StartResponse
    from _typeshed.wsgi import WSGIApplication
    from _typeshed.wsgi import WSGIEnvironment

    from .app import Flask


class NoAppException(click.UsageError):
    """Raised if an application cannot be found or loaded."""


def find_best_app(module: ModuleType) -> Flask:
    """Given a module instance this tries to find the best possible
    application in the module or raises an exception.
    """
    from . import Flask

    # Search for the most common names first.
    for attr_name in ("app", "application"):
        app = getattr(module, attr_name, None)

        if isinstance(app, Flask):
            return app

    # Otherwise find the only object that is a Flask instance.
    matches = [v for v in module.__dict__.values() if isinstance(v, Flask)]

    if len(matches) == 1:
        return matches[0]
    elif len(matches) > 1:
        raise NoAppException(
            "Detected multiple Flask applications in module"
            f" '{module.__name__}'. Use '{module.__name__}:name'"
            " to specify the correct one."
        )

    # Search for app factory functions.
    for attr_name in ("create_app", "make_app"):
        app_factory = getattr(module, attr_name, None)

        if inspect.isfunction(app_factory):
            try:
                app = app_factory()

                if isinstance(app, Flask):
                    return app
            except TypeError as e:
                if not _called_with_wrong_args(app_factory):
                    raise

                raise NoAppException(
                    f"Detected factory '{attr_name}' in module '{module.__name__}',"
                    " but could not call it without arguments. Use"
                    f" '{module.__name__}:{attr_name}(args)'"
                    " to specify arguments."
                ) from e

    raise NoAppException(
        "Failed to find Flask application or factory in module"
        f" '{module.__name__}'. Use '{module.__name__}:name'"
        " to specify one."
    )


def _called_with_wrong_args(f: t.Callable[..., Flask]) -> bool:
    """Check whether calling a function raised a ``TypeError`` because
    the call failed or because something in the factory raised the
    error.

    :param f: The function that was called.
    :return: ``True`` if the call failed.
    """
    tb = sys.exc_info()[2]

    try:
        while tb is not None:
            if tb.tb_frame.f_code is f.__code__:
                # In the function, it was called successfully.
                return False

            tb = tb.tb_next

        # Didn't reach the function.
        return True
    finally:
        # Delete tb to break a circular reference.
        # https://docs.python.org/2/library/sys.html#sys.exc_info
        del tb


def find_app_by_string(module: ModuleType, app_name: str) -> Flask:
    """Check if the given string is a variable name or a function. Call
    a function to get the app instance, or return the variable directly.
    """
    from . import Flask

    # Parse app_name as a single expression to determine if it's a valid
    # attribute name or function call.
    try:
        expr = ast.parse(app_name.strip(), mode="eval").body
    except SyntaxError:
        raise NoAppException(
            f"Failed to parse {app_name!r} as an attribute name or function call."
        ) from None

    if isinstance(expr, ast.Name):
        name = expr.id
        args = []
        kwargs = {}
    elif isinstance(expr, ast.Call):
        # Ensure the function name is an attribute name only.
        if not isinstance(expr.func, ast.Name):
            raise NoAppException(
                f"Function reference must be a simple name: {app_name!r}."
            )

        name = expr.func.id

        # Parse the positional and keyword arguments as literals.
        try:
            args = [ast.literal_eval(arg) for arg in expr.args]
            kwargs = {
                kw.arg: ast.literal_eval(kw.value)
                for kw in expr.keywords
                if kw.arg is not None
            }
        except ValueError:
            # literal_eval gives cryptic error messages, show a generic
            # message with the full expression instead.
            raise NoAppException(
                f"Failed to parse arguments as literal values: {app_name!r}."
            ) from None
    else:
        raise NoAppException(
            f"Failed to parse {app_name!r} as an attribute name or function call."
        )

    try:
        attr = getattr(module, name)
    except AttributeError as e:
        raise NoAppException(
            f"Failed to find attribute {name!r} in {module.__name__!r}."
        ) from e

    # If the attribute is a function, call it with any args and kwargs
    # to get the real application.
    if inspect.isfunction(attr):
        try:
            app = attr(*args, **kwargs)
        except TypeError as e:
            if not _called_with_wrong_args(attr):
                raise

            raise NoAppException(
                f"The factory {app_name!r} in module"
                f" {module.__name__!r} could not be called with the"
                " specified arguments."
            ) from e
    else:
        app = attr

    if isinstance(app, Flask):
        return app

    raise NoAppException(
        "A valid Flask application 
[truncated — 29825 more characters]
```

### backend/fetchai-env/lib/python3.11/site-packages/pip/_internal/models/index.py

```python
import urllib.parse


class PackageIndex:
    """Represents a Package Index and provides easier access to endpoints"""

    __slots__ = ["url", "netloc", "simple_url", "pypi_url", "file_storage_domain"]

    def __init__(self, url: str, file_storage_domain: str) -> None:
        super().__init__()
        self.url = url
        self.netloc = urllib.parse.urlsplit(url).netloc
        self.simple_url = self._url_for_path("simple")
        self.pypi_url = self._url_for_path("pypi")

        # This is part of a temporary hack used to block installs of PyPI
        # packages which depend on external urls only necessary until PyPI can
        # block such packages themselves
        self.file_storage_domain = file_storage_domain

    def _url_for_path(self, path: str) -> str:
        return urllib.parse.urljoin(self.url, path)


PyPI = PackageIndex("https://pypi.org/", file_storage_domain="files.pythonhosted.org")
TestPyPI = PackageIndex(
    "https://test.pypi.org/", file_storage_domain="test-files.pythonhosted.org"
)

```

[1876 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]