-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separated out Members from clubs microservice
- Loading branch information
0 parents
commit d1a7973
Showing
14 changed files
with
1,120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
name: Auto Linting and Formatting | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
linting: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.x' | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install ruff | ||
- name: Lint with ruff | ||
run: ruff check --fix *.py | ||
|
||
- name: Format with ruff | ||
run: ruff format *.py | ||
|
||
- name: Remove ruff cache | ||
run: rm -rf .ruff_cache | ||
|
||
- uses: stefanzweifel/git-auto-commit-action@v5 | ||
with: | ||
commit_message: Apply Linting & Formatting Fixes | ||
|
||
# - name: Remove Linting Branch | ||
# run: | | ||
# if git rev-parse --verify linting >/dev/null 2>&1; then | ||
# git push origin --delete linting | ||
# fi | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.venv/ | ||
.vscode/ | ||
.in | ||
.out | ||
__pycache__/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# cache dependencies | ||
FROM python:3.12 AS python_cache | ||
ENV VIRTUAL_ENV=/venv | ||
ENV PATH="$VIRTUAL_ENV/bin:$PATH" | ||
WORKDIR /cache/ | ||
COPY requirements.txt . | ||
RUN python -m venv /venv | ||
RUN pip install -r requirements.txt | ||
|
||
# build and start | ||
FROM python:3.12-slim AS build | ||
EXPOSE 80 | ||
WORKDIR /app | ||
ENV VIRTUAL_ENV=/venv | ||
ENV PATH="$VIRTUAL_ENV/bin:$PATH" | ||
COPY --from=python_cache /venv /venv | ||
COPY . . | ||
RUN strawberry export-schema main > schema.graphql | ||
ENTRYPOINT [ "./entrypoint.sh" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# _MEMBERS_ MICRO-SERVICE | ||
|
||
This is a microservice using FastAPI + Strawberry + MongoDB. | ||
Contains code for queries, mutations, types and models for the members data and services specifically. | ||
|
||
## How to use | ||
1. Go to [https://github.com/Clubs-Council-IIITH/services](https://github.com/Clubs-Council-IIITH/services) | ||
2. Follow the steps given in the README.md file at that page. | ||
|
||
--- | ||
|
||
## FOR DEVELOPERS | ||
_URL_ -> http://members/graphql (For using in single gateway) | ||
|
||
> ### QUERIES | ||
> ### MUTATIONS |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from os import getenv | ||
|
||
from pymongo import MongoClient | ||
|
||
|
||
# get mongodb URI and database name from environment variale | ||
MONGO_URI = "mongodb://{}:{}@mongo:{}/".format( | ||
getenv("MONGO_USERNAME", default="username"), | ||
getenv("MONGO_PASSWORD", default="password"), | ||
getenv("MONGO_PORT", default="27017"), | ||
) | ||
MONGO_DATABASE = getenv("MONGO_DATABASE", default="default") | ||
|
||
# instantiate mongo client | ||
client = MongoClient(MONGO_URI) | ||
|
||
# get database | ||
db = client[MONGO_DATABASE] | ||
membersdb = db.members | ||
|
||
try: | ||
# check if the members index exists | ||
if "unique_members" in membersdb.index_information(): | ||
print("The members index exists.") | ||
else: | ||
# create the index | ||
membersdb.create_index( | ||
[("cid", 1), ("uid", 1)], unique=True, name="unique_members" | ||
) | ||
print("The members index was created.") | ||
|
||
print(membersdb.index_information()) | ||
except Exception: | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/bash | ||
|
||
cp ./schema.graphql /subgraphs/clubs.graphql | ||
uvicorn main:app --host 0.0.0.0 --port 80 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import strawberry | ||
from strawberry.tools import create_type | ||
from strawberry.fastapi import GraphQLRouter | ||
|
||
from fastapi import FastAPI | ||
|
||
from os import getenv | ||
|
||
# override PyObjectId and Context scalars | ||
from models import PyObjectId | ||
from otypes import Context, PyObjectIdType | ||
|
||
# import all queries and mutations | ||
from queries import queries | ||
from mutations import mutations | ||
|
||
|
||
# check whether running in debug mode | ||
DEBUG = int(getenv("GLOBAL_DEBUG", 0)) | ||
|
||
# create query types | ||
Query = create_type("Query", queries) | ||
|
||
# create mutation types | ||
Mutation = create_type("Mutation", mutations) | ||
|
||
|
||
# override context getter | ||
async def get_context() -> Context: | ||
return Context() | ||
|
||
|
||
# initialize federated schema | ||
schema = strawberry.federation.Schema( | ||
query=Query, | ||
mutation=Mutation, | ||
enable_federation_2=True, | ||
scalar_overrides={PyObjectId: PyObjectIdType}, | ||
) | ||
|
||
DEBUG = getenv("SERVICES_DEBUG", "False").lower() in ("true", "1", "t") | ||
|
||
# serve API with FastAPI router | ||
gql_app = GraphQLRouter(schema, graphiql=True, context_getter=get_context) | ||
app = FastAPI( | ||
debug=DEBUG, | ||
title="CC Clubs Microservice", | ||
desciption="Handles Data of Clubs and Members", | ||
) | ||
app.include_router(gql_app, prefix="/graphql") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
from bson import ObjectId | ||
from pydantic import ( | ||
BaseModel, | ||
ConfigDict, | ||
Field, | ||
field_validator, | ||
ValidationInfo, | ||
) | ||
from pydantic_core import core_schema | ||
from typing import Any, List | ||
|
||
|
||
# for handling mongo ObjectIds | ||
class PyObjectId(ObjectId): | ||
@classmethod | ||
def __get_pydantic_core_schema__(cls, source_type: Any, handler): | ||
return core_schema.union_schema( | ||
[ | ||
# check if it's an instance first before doing any further work | ||
core_schema.is_instance_schema(ObjectId), | ||
core_schema.no_info_plain_validator_function(cls.validate), | ||
], | ||
serialization=core_schema.to_string_ser_schema(), | ||
) | ||
|
||
@classmethod | ||
def validate(cls, v): | ||
if not ObjectId.is_valid(v): | ||
raise ValueError("Invalid ObjectId") | ||
return ObjectId(v) | ||
|
||
@classmethod | ||
def __get_pydantic_json_schema__(cls, field_schema): | ||
field_schema.update(type="string") | ||
|
||
|
||
class Roles(BaseModel): | ||
rid: str | None = Field(None, description="Unique Identifier for a role") | ||
name: str = Field(..., min_length=1, max_length=99) | ||
start_year: int = Field(..., ge=2010, le=2050) | ||
end_year: int | None = Field(None, gt=2010, le=2051) | ||
approved: bool = False | ||
rejected: bool = False | ||
deleted: bool = False | ||
|
||
# Validators | ||
@field_validator("end_year") | ||
def check_end_year(cls, value, info: ValidationInfo): | ||
if value is not None and value < info.data["start_year"]: | ||
return None | ||
return value | ||
|
||
@field_validator("rejected") | ||
def check_status(cls, value, info: ValidationInfo): | ||
if info.data["approved"] is True and value is True: | ||
raise ValueError("Role cannot be both approved and rejected") | ||
return value | ||
|
||
model_config = ConfigDict( | ||
arbitrary_types_allowed=True, | ||
str_max_length=100, | ||
validate_assignment=True, | ||
validate_default=True, | ||
validate_return=True, | ||
extra="forbid", | ||
str_strip_whitespace=True, | ||
) | ||
|
||
|
||
class Member(BaseModel): | ||
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id") | ||
cid: str = Field(..., description="Club ID") | ||
uid: str = Field(..., description="User ID") | ||
roles: List[Roles] = Field( | ||
..., description="List of Roles for that specific person" | ||
) | ||
|
||
poc: bool = Field(default_factory=(lambda: 0 == 1), description="Club POC") | ||
|
||
@field_validator("uid", mode="before") | ||
@classmethod | ||
def transform_uid(cls, v): | ||
return v.lower() | ||
|
||
# TODO[pydantic]: The following keys were removed: `json_encoders`. | ||
# Check https://docs.pydantic.dev/dev-v2/migration/#changes-to-config for more information. | ||
model_config = ConfigDict( | ||
arbitrary_types_allowed=True, | ||
str_strip_whitespace=True, | ||
str_max_length=600, | ||
validate_assignment=True, | ||
validate_default=True, | ||
validate_return=True, | ||
extra="forbid", | ||
json_encoders={ObjectId: str}, | ||
populate_by_name=True, | ||
) | ||
|
||
# Separate Coordinator & other members roles option in frontend, for better filtering for all_members_query | ||
|
||
|
||
# TODO: ADD Descriptions for non-direct fields |
Oops, something went wrong.