Skip to content
This repository has been archived by the owner on Feb 5, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
davidkonigsberg committed Jan 2, 2024
2 parents 65e8018 + ea09c46 commit 99890e5
Show file tree
Hide file tree
Showing 2,681 changed files with 51,872 additions and 53,980 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/seed_container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Build seed container

on:
push:
branches:
- main
workflow_dispatch:

jobs:
compile:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: fernapi
password: ${{ secrets.FERN_API_DOCKERHUB_PASSWORD }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: fernapi/python-seed
tags: |
type=sha
latest
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
file: ./docker/seed/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
# use short SHA if modded, or just use latest if nothing changed
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ dist/
__pycache__/
poetry.toml
.idea/
.dmypy.json
22 changes: 22 additions & 0 deletions docker/seed/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM python:3.10
COPY pyproject.toml ./pyproject.toml
COPY poetry.lock ./poetry.lock
COPY ./src ./src


# Setup pyenv
RUN apt-get install -y git
RUN git clone --depth=1 https://github.com/pyenv/pyenv.git .pyenv
ENV PYENV_ROOT="${HOME}/.pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"

RUN pyenv install 3.9
RUN pyenv install 3.8

# Setup poetry
RUN pip install poetry &&\
poetry config virtualenvs.create false &&\
poetry install


CMD [ "poetry" ]
2 changes: 1 addition & 1 deletion seed/fastapi/api-wide-base-path/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .core.abstract_fern_service import AbstractFernService
from .core.exceptions import default_exception_handler, fern_http_exception_handler, http_exception_handler
from .core.exceptions.fern_http_exception import FernHTTPException
from .resources.service.service.service import AbstractServiceService
from .service.service.service import AbstractServiceService


def register(
Expand Down

This file was deleted.

76 changes: 76 additions & 0 deletions seed/fastapi/api-wide-base-path/service/service/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# This file was auto-generated by Fern from our API Definition.

import abc
import functools
import inspect
import logging
import typing

import fastapi
import starlette

from ...core.abstract_fern_service import AbstractFernService
from ...core.exceptions.fern_http_exception import FernHTTPException
from ...core.route_args import get_route_args


class AbstractServiceService(AbstractFernService):
"""
AbstractServiceService is an abstract class containing the methods that you should implement.
Each method is associated with an API route, which will be registered
with FastAPI when you register your implementation using Fern's register()
function.
"""

@abc.abstractmethod
def post(self, *, service_param: str, endpoint_param: int) -> None:
...

"""
Below are internal methods used by Fern to register your implementation.
You can ignore them.
"""

@classmethod
def _init_fern(cls, router: fastapi.APIRouter) -> None:
cls.__init_post(router=router)

@classmethod
def __init_post(cls, router: fastapi.APIRouter) -> None:
endpoint_function = inspect.signature(cls.post)
new_parameters: typing.List[inspect.Parameter] = []
for index, (parameter_name, parameter) in enumerate(endpoint_function.parameters.items()):
if index == 0:
new_parameters.append(parameter.replace(default=fastapi.Depends(cls)))
elif parameter_name == "service_param":
new_parameters.append(parameter.replace(default=fastapi.Path(...)))
elif parameter_name == "endpoint_param":
new_parameters.append(parameter.replace(default=fastapi.Path(...)))
else:
new_parameters.append(parameter)
setattr(cls.post, "__signature__", endpoint_function.replace(parameters=new_parameters))

@functools.wraps(cls.post)
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> None:
try:
return cls.post(*args, **kwargs)
except FernHTTPException as e:
logging.getLogger(f"{cls.__module__}.{cls.__name__}").warn(
f"Endpoint 'post' unexpectedly threw {e.__class__.__name__}. "
+ f"If this was intentional, please add {e.__class__.__name__} to "
+ "the endpoint's errors list in your Fern Definition."
)
raise e

# this is necessary for FastAPI to find forward-ref'ed type hints.
# https://github.com/tiangolo/fastapi/pull/5077
wrapper.__globals__.update(cls.post.__globals__)

router.post(
path="/test/{path_param}/{service_param}/{endpoint_param}",
response_model=None,
status_code=starlette.status.HTTP_204_NO_CONTENT,
description=AbstractServiceService.post.__doc__,
**get_route_args(cls.post, default_tag="service"),
)(wrapper)
4 changes: 3 additions & 1 deletion seed/fastapi/audiences/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# This file was auto-generated by Fern from our API Definition.

from .resources import Imported, ImportingType, OptionalString, commons, folder_a, folder_b, folder_c, foo
from . import commons, folder_a, folder_b, folder_c, foo
from .commons import Imported
from .foo import ImportingType, OptionalString

__all__ = ["Imported", "ImportingType", "OptionalString", "commons", "folder_a", "folder_b", "folder_c", "foo"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import datetime as dt
import typing

from ....core.datetime_utils import serialize_datetime
from ...core.datetime_utils import serialize_datetime

try:
import pydantic.v1 as pydantic # type: ignore
Expand Down
71 changes: 71 additions & 0 deletions seed/fastapi/audiences/folder_a/service/service/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# This file was auto-generated by Fern from our API Definition.

import abc
import functools
import inspect
import logging
import typing

import fastapi

from ....core.abstract_fern_service import AbstractFernService
from ....core.exceptions.fern_http_exception import FernHTTPException
from ....core.route_args import get_route_args
from ..types.response import Response


class AbstractFolderAServiceService(AbstractFernService):
"""
AbstractFolderAServiceService is an abstract class containing the methods that you should implement.
Each method is associated with an API route, which will be registered
with FastAPI when you register your implementation using Fern's register()
function.
"""

@abc.abstractmethod
def get_direct_thread(self) -> Response:
...

"""
Below are internal methods used by Fern to register your implementation.
You can ignore them.
"""

@classmethod
def _init_fern(cls, router: fastapi.APIRouter) -> None:
cls.__init_get_direct_thread(router=router)

@classmethod
def __init_get_direct_thread(cls, router: fastapi.APIRouter) -> None:
endpoint_function = inspect.signature(cls.get_direct_thread)
new_parameters: typing.List[inspect.Parameter] = []
for index, (parameter_name, parameter) in enumerate(endpoint_function.parameters.items()):
if index == 0:
new_parameters.append(parameter.replace(default=fastapi.Depends(cls)))
else:
new_parameters.append(parameter)
setattr(cls.get_direct_thread, "__signature__", endpoint_function.replace(parameters=new_parameters))

@functools.wraps(cls.get_direct_thread)
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> Response:
try:
return cls.get_direct_thread(*args, **kwargs)
except FernHTTPException as e:
logging.getLogger(f"{cls.__module__}.{cls.__name__}").warn(
f"Endpoint 'get_direct_thread' unexpectedly threw {e.__class__.__name__}. "
+ f"If this was intentional, please add {e.__class__.__name__} to "
+ "the endpoint's errors list in your Fern Definition."
)
raise e

# this is necessary for FastAPI to find forward-ref'ed type hints.
# https://github.com/tiangolo/fastapi/pull/5077
wrapper.__globals__.update(cls.get_direct_thread.__globals__)

router.get(
path="/",
response_model=Response,
description=AbstractFolderAServiceService.get_direct_thread.__doc__,
**get_route_args(cls.get_direct_thread, default_tag="folder_a.service"),
)(wrapper)
28 changes: 28 additions & 0 deletions seed/fastapi/audiences/folder_a/service/types/response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing

from ....core.datetime_utils import serialize_datetime
from ....folder_b.common.types.foo import Foo

try:
import pydantic.v1 as pydantic # type: ignore
except ImportError:
import pydantic # type: ignore


class Response(pydantic.BaseModel):
foo: typing.Optional[Foo]

def json(self, **kwargs: typing.Any) -> str:
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
return super().json(**kwargs_with_defaults)

def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
return super().dict(**kwargs_with_defaults)

class Config:
extra = pydantic.Extra.forbid
json_encoders = {dt.datetime: serialize_datetime}
28 changes: 28 additions & 0 deletions seed/fastapi/audiences/folder_b/common/types/foo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing

from ....core.datetime_utils import serialize_datetime
from ....folder_c.common.types.foo import Foo as folder_c_common_types_foo_Foo

try:
import pydantic.v1 as pydantic # type: ignore
except ImportError:
import pydantic # type: ignore


class Foo(pydantic.BaseModel):
foo: typing.Optional[folder_c_common_types_foo_Foo]

def json(self, **kwargs: typing.Any) -> str:
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
return super().json(**kwargs_with_defaults)

def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
return super().dict(**kwargs_with_defaults)

class Config:
extra = pydantic.Extra.forbid
json_encoders = {dt.datetime: serialize_datetime}
Loading

0 comments on commit 99890e5

Please sign in to comment.