Skip to content

Commit

Permalink
Merge pull request #1 from arXiv/basic-repository-setup
Browse files Browse the repository at this point in the history
basic flask setup
  • Loading branch information
kyokukou authored Nov 4, 2024
2 parents 0a0318e + 8f75a94 commit 371000f
Show file tree
Hide file tree
Showing 15 changed files with 2,545 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
32 changes: 32 additions & 0 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python application

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.11"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest poetry coverage
poetry install
- name: Test with pytest
run: |
poetry run pytest --cov=oaipmh --cov-fail-under=40 tests
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,4 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.python-version
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# arxiv_oaipmh
handles requests to the OAI PMH service

# run locally
install dependencies:
poetry install

run:
python main.py

tests:

pytest tests
11 changes: 11 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Simple file to run oaipmh in debug mode.
Run as `python main.py`"""
import os
from oaipmh.factory import create_web_app

if __name__ == "__main__":
os.environ['TEMPLATES_AUTO_RELOAD'] = "1"
os.environ['DEBUG'] = "1"
app = create_web_app()
app.run(debug=True, port=8080)
37 changes: 37 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[mypy]
#mypy_path = $MYPYPATH

#
# Covered by --strict, with some turned off:
#
disallow_untyped_defs=True
check_untyped_defs=True
# currently an issue with sql alchemy
disallow_subclassing_any=false
# Need to experiment/think about this one:
disallow_any_decorated=false
warn_redundant_casts=True
warn_return_any=True
warn_unused_ignores=True
# this seems to be at least somewhat non-functioning:
warn_unused_configs=True
#may be worth reconsidering this one:
no_implicit_optional=True
strict_optional=True
allow_redefinition=True


#
# Other:
#
ignore_missing_imports=True
follow_imports=silent

#
# Plugins:
#
plugins = pydantic.mypy

[oaipmh.*]
disallow_untyped_calls=True

1 change: 1 addition & 0 deletions oaipmh/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""OAI-PMH."""
31 changes: 31 additions & 0 deletions oaipmh/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
import warnings
from typing import Optional

import arxiv.config as arxiv_base

import logging
log = logging.getLogger(__name__)

class Settings(arxiv_base.Settings):
TESTING: bool = True
TEMPLATES_AUTO_RELOAD: Optional[bool] = None

SQLALCHEMY_MAX_OVERFLOW: Optional[int] = 0
SQLALCHEMY_POOL_SIZE: Optional[int] = 10

APPLICATION_ROOT: Optional[str] = None

def check(self) -> None:
"""A check and fix up of a settings object."""
if 'sqlite' in self.CLASSIC_DB_URI:
if not self.TESTING:
log.warning(f"using SQLite DB at {self.CLASSIC_DB_URI}")
self.SQLALCHEMY_MAX_OVERFLOW = None
self.SQLALCHEMY_POOL_SIZE = None

if (os.environ.get("FLASK_ENV", False) == "production"
and "sqlite" in self.CLASSIC_DB_URI):
warnings.warn(
"Using sqlite in CLASSIC_DB_URI in production environment"
)
66 changes: 66 additions & 0 deletions oaipmh/factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import logging

from flask import Flask
from flask_s3 import FlaskS3
from flask.logging import default_handler

from arxiv.base import Base
from arxiv.db import config_query_timing, configure_db

from oaipmh.config import Settings
from oaipmh import routes

s3 = FlaskS3()

def create_web_app(**kwargs) -> Flask: # type: ignore
"""Initialize an instance of the browse web application."""
root = logging.getLogger()
root.addHandler(default_handler)

settings = Settings(**kwargs)
settings.check()

app = Flask('oaipmh')
app.config.from_object(settings)

app.engine = configure_db(settings) # type: ignore

Base(app)

# Log long SQL queries
#config_query_timing(app.engine, 0.2, 8) # type: ignore

app.register_blueprint(routes.blueprint)
s3.init_app(app)

app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
if not app.jinja_env.globals:
app.jinja_env.globals = {}

return app


def setup_trace(name: str, app: Flask): # type: ignore
"""Setup GCP trace and logging."""
from opentelemetry import trace
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.cloud_trace_propagator import (
CloudTraceFormatPropagator,
)
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

# https://cloud.google.com/trace/docs/setup/python-ot#initialize_flask
set_global_textmap(CloudTraceFormatPropagator())
tracer_provider = TracerProvider()
cloud_trace_exporter = CloudTraceSpanExporter()
tracer_provider.add_span_processor(
BatchSpanProcessor(cloud_trace_exporter)
)
trace.set_tracer_provider(tracer_provider)
tracer = trace.get_tracer(name)
FlaskInstrumentor().instrument_app(app)
return tracer
8 changes: 8 additions & 0 deletions oaipmh/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from flask import Blueprint

blueprint = Blueprint('general', __name__)


@blueprint.route("/oai", methods=['GET', 'HEAD'])
def oai(): # type: ignore
return "working!", 200, {}
Loading

0 comments on commit 371000f

Please sign in to comment.