Skip to content

Commit

Permalink
Merge pull request #68 from NERSC/black
Browse files Browse the repository at this point in the history
Add black workflow
  • Loading branch information
cjh1 authored Oct 6, 2023
2 parents 2af1651 + a7436e5 commit 55af1e2
Show file tree
Hide file tree
Showing 29 changed files with 135 additions and 106 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: black

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

jobs:
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: psf/black@stable
with:
options: "--check --verbose"
jupyter: false
14 changes: 14 additions & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: ruff

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

jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: chartboost/ruff-action@v1
1 change: 0 additions & 1 deletion docs/gen_examples.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from pathlib import Path
import os
import json

replace = Path("examples_dev") / "replacement.json"
Expand Down
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,17 @@ classifiers = [
exclude = '''
(
src/sfapi_client/_sync |
src/sfapi_client/_async/_models.py
src/sfapi_client/_async/_models.py |
sfapi_client/examples/
)
'''

[tool.ruff]
exclude = [
"src/sfapi_client/_sync",
"src/sfapi_client/_async/_models.py"
]

[project.optional-dependencies]
docs = [
"mkdocs-material",
Expand Down
13 changes: 5 additions & 8 deletions scripts/run.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import os
import re
from pathlib import Path
import json

import typer
import unasync
from pathlib import Path
from tempfile import TemporaryDirectory
from urllib.parse import urlparse
from typing import List, Optional

from datamodel_code_generator import InputFileType, generate
import typer


cli = typer.Typer()
Expand Down Expand Up @@ -91,10 +88,10 @@ def run_unasync():
# can't determine the type, so we have to patch things up, for now they are all
# string based enums.
def _to_str_enum(code: str) -> str:
pattern = re.compile(rf"(.*)\(Enum\)(.*)", re.DOTALL)
pattern = re.compile(r"(.*)\(Enum\)(.*)", re.DOTALL)

while pattern.match(code):
code = re.sub(pattern, rf"\1(str, Enum)\2", code)
code = re.sub(pattern, r"\1(str, Enum)\2", code)

return code

Expand Down Expand Up @@ -151,9 +148,9 @@ def _from_json(json: Path, class_name: str) -> str:


#
# Generate models using datamodel-codegen using OpenAPI spec and a sample JSON job status output.
# Eventually is would be nice to move the job status model into SF API, so cold then just rely
# only on the OpenAPI spec.
# Generate models using datamodel-codegen using OpenAPI spec and a sample JSON job
# status output. Eventually is would be nice to move the job status model into SF
# API, so cold then just rely only on the OpenAPI spec.
#
@cli.command(name="codegen")
def openapimodel_codegen(
Expand Down
10 changes: 5 additions & 5 deletions src/sfapi_client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .client import AsyncClient
from .client import Client
from .exceptions import SfApiError
from ._models import StatusValue
from ._models.resources import Resource
from .client import AsyncClient # noqa: F401
from .client import Client # noqa: F401
from .exceptions import SfApiError # noqa: F401
from ._models import StatusValue # noqa: F401
from ._models.resources import Resource # noqa: F401
4 changes: 1 addition & 3 deletions src/sfapi_client/_async/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from .compute import Machine, AsyncCompute
from ..exceptions import SfApiError
from .._models import (
JobOutput as JobStatusResponse,
AppRoutersComputeModelsStatus as JobStatus,
Changelog as ChangelogItem,
Config as ConfItem,
Outage,
Expand Down Expand Up @@ -256,7 +254,7 @@ async def __aenter__(self):

async def _oauth2_session(self):
if self._client_id is None:
raise SfApiError(f"No credentials have been provides")
raise SfApiError("No credentials have been provides")

if self.__oauth2_session is None:
# Create a new session if we haven't already
Expand Down
16 changes: 8 additions & 8 deletions src/sfapi_client/_async/compute.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import asyncio
from typing import Dict, List, Optional, Union, Callable
import json
from enum import Enum
from pydantic import BaseModel, PrivateAttr, ConfigDict
from pydantic import PrivateAttr, ConfigDict
from functools import wraps

from ..exceptions import SfApiError
from .._utils import _ASYNC_SLEEP
from .jobs import AsyncJobSacct, AsyncJobSqueue, AsyncJobSqueue, JobCommand
from .jobs import AsyncJobSacct, AsyncJobSqueue, JobCommand
from .._models import (
AppRoutersStatusModelsStatus as ComputeBase,
Task,
Expand All @@ -30,7 +28,7 @@ def check_auth(method: Callable):
def wrapper(self, *args, **kwargs):
if self.client._client_id is None:
raise SfApiError(
f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client."
f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client." # noqa: E501
)
elif self.status in [StatusValue.unavailable]:
raise SfApiError(
Expand All @@ -42,7 +40,7 @@ def wrapper(self, *args, **kwargs):


class AsyncCompute(ComputeBase):
client: Optional["AsyncClient"]
client: Optional["AsyncClient"] # noqa: F821
_monitor: AsyncJobMonitor = PrivateAttr()

model_config = ConfigDict(arbitrary_types_allowed=True)
Expand Down Expand Up @@ -76,8 +74,10 @@ async def _wait_for_task(self, task_id) -> str:
async def submit_job(self, script: Union[str, AsyncRemotePath]) -> AsyncJobSqueue:
"""Submit a job to the compute resource
:param script: Path to file on the compute system, or script to run beginning with `#!`.
:return: Object containing information about the job, its job id, and status on the system.
:param script: Path to file on the compute system, or script to run beginning
with `#!`.
:return: Object containing information about the job, its job id, and status
on the system.
"""

is_path: bool = True
Expand Down
11 changes: 6 additions & 5 deletions src/sfapi_client/_async/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ def check_auth(method: Callable):
def wrapper(self, *args, **kwargs):
if self._client_id is None:
raise SfApiError(
f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client."
f"Cannot call {self.__class__.__name__}.{method.__name__}() with an unauthenticated client." # noqa: E501
)
return method(self, *args, **kwargs)

return wrapper


class AsyncGroupMember(GroupMemberBase):
client: Optional["AsyncClient"]
client: Optional["AsyncClient"] # noqa: F821

model_config = ConfigDict(arbitrary_types_allowed=True)

Expand All @@ -30,13 +30,14 @@ async def user(self) -> "AsyncUser":
return await AsyncUser._fetch_user(self.client, self.name)


# Note: We can't use our generated model as we want user => members ( to avoid confusion with User model )
# Note: We can't use our generated model as we want user => members ( to avoid
# confusion with User model )
class AsyncGroup(BaseModel):
"""
A user group.
"""

client: Optional["AsyncClient"]
client: Optional["AsyncClient"] # noqa: F821
gid: Optional[int]
name: Optional[str]
users_: Optional[List[GroupMemberBase]] = Field(..., alias="users")
Expand Down Expand Up @@ -114,7 +115,7 @@ def _set_client(m):

@staticmethod
@check_auth
async def _fetch_group(client: "AsyncClient", name):
async def _fetch_group(client: "AsyncClient", name): # noqa: F821
response = await client.get(f"account/groups/{name}")

json_response = response.json()
Expand Down
27 changes: 14 additions & 13 deletions src/sfapi_client/_async/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import sys
import math
from abc import ABC, abstractmethod
from typing import Any, Optional, Dict, List, ClassVar
from typing import Any, Optional, Dict, List, ClassVar, Union
from .._utils import _ASYNC_SLEEP
from ..exceptions import SfApiError
from .._models.job_status_response_sacct import OutputItem as JobSacctBase
from .._models.job_status_response_squeue import OutputItem as JobSqueueBase
from .._models import AppRoutersComputeModelsStatus as JobResponseStatus

from pydantic import BaseModel, Field, field_validator
from pydantic import BaseModel, field_validator

from .._jobs import JobCommand
from .._jobs import JobStateResponse
Expand All @@ -18,7 +18,7 @@


async def _fetch_raw_state(
compute: "AsyncCompute",
compute: "AsyncCompute", # noqa: F821
jobids: Optional[List[int]] = None,
user: Optional[str] = None,
partition: Optional[str] = None,
Expand Down Expand Up @@ -55,7 +55,7 @@ async def _fetch_raw_state(

async def _fetch_jobs(
job_type: Union["AsyncJobSacct", "AsyncJobSqueue"],
compute: "AsyncCompute",
compute: "AsyncCompute", # noqa: F821
jobids: Optional[List[int]] = None,
user: Optional[str] = None,
partition: Optional[str] = None,
Expand All @@ -76,7 +76,7 @@ class AsyncJob(BaseModel, ABC):
Models a job submitted to run on a compute resource.
"""

compute: Optional["AsyncCompute"] = None
compute: Optional["AsyncCompute"] = None # noqa: F821
state: Optional[JobState] = None
jobid: Optional[str] = None

Expand All @@ -97,7 +97,7 @@ async def update(self):
job_state = await self._fetch_state()
self._update(job_state)

def _update(self, new_job_state: Any) -> Job:
def _update(self, new_job_state: Any) -> Job: # noqa: F821
for k in new_job_state.model_fields_set:
v = getattr(new_job_state, k)
setattr(self, k, v)
Expand Down Expand Up @@ -129,8 +129,8 @@ async def complete(self, timeout: int = sys.maxsize):
"""
Wait for a job to move into a terminal state.
:param timeout: The maximum time to wait in seconds, the actually wait time will be in
10 second increments.
:param timeout: The maximum time to wait in seconds, the actually
wait time will be in 10 second increments.
:raises TimeoutError: if timeout is reached
"""
return await self._wait_until_complete(timeout)
Expand All @@ -139,8 +139,8 @@ async def running(self, timeout: int = sys.maxsize):
"""
Wait for a job to move into running state.
:param timeout: The maximum time to wait in seconds, the actually wait time will be in
10 second increments.
:param timeout: The maximum time to wait in seconds, the actually wait
time will be in 10 second increments.
:raises TimeoutError: if timeout if reached
"""
state = await self._wait_until([JobState.RUNNING] + TERMINAL_STATES, timeout)
Expand All @@ -155,7 +155,8 @@ async def cancel(self, wait=False):
"""
Cancel a running job
:param wait: True, to wait for job be to cancel, otherwise returns when cancellation
:param wait: True, to wait for job be to cancel, otherwise returns when
cancellation
has been submitted.
:type wait: bool
Expand Down Expand Up @@ -199,7 +200,7 @@ async def _fetch_state(self):
@classmethod
async def _fetch_jobs(
cls,
compute: "AsyncCompute",
compute: "AsyncCompute", # noqa: F821
jobids: Optional[List[int]] = None,
user: Optional[str] = None,
partition: Optional[str] = None,
Expand Down Expand Up @@ -241,7 +242,7 @@ async def _fetch_state(self):
@classmethod
async def _fetch_jobs(
cls,
compute: "AsyncCompute",
compute: "AsyncCompute", # noqa: F821
jobids: Optional[List[int]] = None,
user: Optional[str] = None,
partition: Optional[str] = None,
Expand Down
Loading

0 comments on commit 55af1e2

Please sign in to comment.