Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kongzii committed Jun 4, 2024
1 parent 8d6881d commit c30ed6d
Show file tree
Hide file tree
Showing 14 changed files with 5,218 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Docker specific ignores:
.git

# .gitignore ignores:
.env
.agents_workspace
.cache
__pycache__
*.egg-info
logs
.mypy_cache
.pytest_cache
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TAVILY_API_KEY=
15 changes: 15 additions & 0 deletions .github/actions/python_prepare/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: "Prepare Python environment"
description: "Set up Python and install dependencies"
runs:
using: "composite"
steps:
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: 3.10.14
- name: Install Poetry
shell: bash
run: curl -sSL https://install.python-poetry.org | python3 -
- name: Install dependencies
shell: bash
run: poetry install
47 changes: 47 additions & 0 deletions .github/workflows/python_cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Python CD

on:
pull_request: # TODO: Remove before merge to main.
push:
branches: [main]
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout Repository
uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages.
# Once published, the packages are scoped to the account defined here.
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image.
# The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
66 changes: 66 additions & 0 deletions .github/workflows/python_ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Python CI

on:
pull_request:
push:
branches: [main]
workflow_dispatch:

jobs:
mypy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: ./.github/actions/python_prepare
- name: Run mypy
run: poetry run mypy

pytest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: ./.github/actions/python_prepare
- name: Run pytest
run: poetry run pytest tests

test-build-image:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Build and push Docker image
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56
with:
push: false

black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/python_prepare
- name: Check with black
run: poetry run black --check .

autoflake:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/python_prepare
- name: Check with autoflake
run: |
poetry run autoflake --in-place --remove-all-unused-imports --remove-unused-variables --recursive .
git diff --exit-code --quiet || exit 1
isort:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/python_prepare
- name: Check with isort
run: |
poetry run isort --profile black .
git diff --exit-code --quiet || exit 1
31 changes: 31 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Install Poetry and create venv in the builder step,
# then copy the venv to the runtime image, so that the runtime image is as small as possible.
FROM --platform=linux/amd64 python:3.10.14-bookworm AS builder

RUN pip install poetry==1.8.2

ENV POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=1 \
POETRY_VIRTUALENVS_CREATE=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache

WORKDIR /app

COPY pyproject.toml poetry.lock ./

RUN --mount=type=cache,target=$POETRY_CACHE_DIR poetry install --no-root --only main

FROM --platform=linux/amd64 python:3.10.14-bookworm AS runtime

ENV VIRTUAL_ENV=/app/.venv \
PATH="/app/.venv/bin:$PATH"

WORKDIR /app

COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}

COPY labs_api ./labs_api

ENV PYTHONPATH=/app

CMD ["bash", "-c", "python labs_api/main.py"]
4 changes: 4 additions & 0 deletions build_and_push.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
# This script builds the docker image and pushes it to the GitHub Container Registry,
# it should be done from Github's CD pipeline, but keeping it here for any testing purposes required in the future.
docker build . -t ghcr.io/gnosis/labs-api:test && docker push ghcr.io/gnosis/labs-api:test
18 changes: 18 additions & 0 deletions labs_api/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import typing as t

from prediction_market_agent_tooling.tools.utils import check_not_none
from pydantic import SecretStr
from pydantic_settings import BaseSettings


class Config(BaseSettings):
HOST: str = "0.0.0.0"
PORT: int = 8080
WORKERS: int = 1
TAVILY_API_KEY: t.Optional[SecretStr] = None

@property
def tavily_api_key(self) -> SecretStr:
return check_not_none(
self.TAVILY_API_KEY, "TAVILY_API_KEY missing in the environment."
)
42 changes: 42 additions & 0 deletions labs_api/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import fastapi
import uvicorn
from config import Config
from fastapi.middleware.cors import CORSMiddleware

from labs_api.config import Config


def create_app() -> fastapi.FastAPI:
app = fastapi.FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

@app.get("/ping/")
def _ping() -> str:
"""Ping Pong!"""
return "pong"

@app.get("/market-insights")
def _market_insights(market_id: str) -> str:
"""Returns markdown formatted market insights for a given market on Omen."""
return f"hello {market_id}"

return app


if __name__ == "__main__":
config = Config()
uvicorn.run(
"labs_api.main:create_app",
factory=True,
host=config.HOST,
port=config.PORT,
workers=config.WORKERS,
reload=False,
log_level="info",
)
36 changes: 36 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[mypy]
python_version = 3.10
files = labs_api/, tests/
plugins = pydantic.mypy
warn_redundant_casts = True
warn_unused_ignores = True
disallow_any_generics = True
warn_return_any = True
check_untyped_defs = True
show_error_codes = True
strict_equality = True
explicit_package_bases = True
show_traceback = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
ignore_missing_imports = True
# Exclude submodules that are themselves not type-checked
exclude = prediction_market_agent/tools/mech/mech/

# See https://github.com/python/mypy/issues/3905#issuecomment-421065323
# We don't want to ignore all missing imports as we want to catch those in our own code
# But for certain libraries they don't have a stub file, so we only enforce import checking for our own libraries.
# Another alternative would be to list out every single dependency that does not have a stub.
[mypy-prediction_market_agent.*]
ignore_missing_imports = False
[mypy-scripts.*]
ignore_missing_imports = False
[mypy-tests.*]
ignore_missing_imports = False

[pydantic-mypy]
# See https://pydantic-docs.helpmanual.io/mypy_plugin/
init_forbid_extra = True
init_typed = True
warn_required_dynamic_aliases = True
warn_untyped_fields = True
Loading

0 comments on commit c30ed6d

Please sign in to comment.