apexdevkit 1.30.3__tar.gz → 1.31.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/PKG-INFO +3 -4
  2. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/__init__.py +3 -0
  3. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/resource.py +1 -1
  4. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/router.py +34 -1
  5. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/__init__.py +2 -1
  6. apexdevkit-1.31.1/apexdevkit/http/httpx/__init__.py +10 -0
  7. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/httpx/hooks.py +13 -0
  8. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/pyproject.toml +18 -12
  9. apexdevkit-1.30.3/apexdevkit/http/httpx/__init__.py +0 -6
  10. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/LICENSE +0 -0
  11. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/README.md +0 -0
  12. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/__init__.py +0 -0
  13. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/annotation/__init__.py +0 -0
  14. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/annotation/deprecate.py +0 -0
  15. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/date.py +0 -0
  16. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/environment.py +0 -0
  17. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/error.py +0 -0
  18. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/builder.py +0 -0
  19. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/dependable.py +0 -0
  20. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/docs.py +0 -0
  21. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/name.py +0 -0
  22. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/response.py +0 -0
  23. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/schema.py +0 -0
  24. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fastapi/service.py +0 -0
  25. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/fluent.py +0 -0
  26. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/formatter.py +0 -0
  27. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/fake.py +0 -0
  28. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/fluent.py +0 -0
  29. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/httpx/client.py +0 -0
  30. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/json.py +0 -0
  31. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/http/url.py +0 -0
  32. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/key_fn.py +0 -0
  33. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/py.typed +0 -0
  34. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/query/__init__.py +0 -0
  35. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/query/generator.py +0 -0
  36. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/query/query.py +0 -0
  37. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/__init__.py +0 -0
  38. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/__init__.py +0 -0
  39. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/database.py +0 -0
  40. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/decorator.py +0 -0
  41. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/interface.py +0 -0
  42. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/mixin.py +0 -0
  43. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/core/multi.py +0 -0
  44. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/in_memory/__init__.py +0 -0
  45. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/in_memory/mixin.py +0 -0
  46. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/in_memory/repository.py +0 -0
  47. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/in_memory/store.py +0 -0
  48. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/sql/__init__.py +0 -0
  49. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/sql/connector.py +0 -0
  50. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/sql/field.py +0 -0
  51. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/sql/mssql.py +0 -0
  52. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/repository/sql/sqlite.py +0 -0
  53. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/security/__init__.py +0 -0
  54. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/security/core.py +0 -0
  55. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/security/hashing.py +0 -0
  56. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/server.py +0 -0
  57. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/testing/__init__.py +0 -0
  58. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/testing/database.py +0 -0
  59. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/testing/fake.py +0 -0
  60. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/testing/rest.py +0 -0
  61. {apexdevkit-1.30.3 → apexdevkit-1.31.1}/apexdevkit/value.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apexdevkit
3
- Version: 1.30.3
3
+ Version: 1.31.1
4
4
  Summary: Apex Development Tools for python.
5
5
  License-File: LICENSE
6
6
  Author: Apex Dev
7
7
  Author-email: dev@apex.ge
8
- Requires-Python: >=3.11
8
+ Requires-Python: >=3.11,<4
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
@@ -13,11 +13,10 @@ Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
14
  Requires-Dist: fastapi
15
15
  Requires-Dist: httpx
16
+ Requires-Dist: pydantic
16
17
  Requires-Dist: pymssql (==2.*)
17
18
  Requires-Dist: python-dotenv
18
19
  Requires-Dist: sentry-sdk[fastapi]
19
- Requires-Dist: tomlkit
20
- Requires-Dist: typer
21
20
  Requires-Dist: uvicorn
22
21
  Description-Content-Type: text/markdown
23
22
 
@@ -1,5 +1,6 @@
1
1
  from apexdevkit.fastapi.builder import FastApiBuilder, RestfulServiceBuilder
2
2
  from apexdevkit.fastapi.dependable import inject
3
+ from apexdevkit.fastapi.router import RestfulRouter, RouterWithHiddenUnderscoreRoutes
3
4
  from apexdevkit.fastapi.service import RestfulRepository
4
5
 
5
6
  __all__ = [
@@ -7,4 +8,6 @@ __all__ = [
7
8
  "RestfulServiceBuilder",
8
9
  "inject",
9
10
  "RestfulRepository",
11
+ "RestfulRouter",
12
+ "RouterWithHiddenUnderscoreRoutes",
10
13
  ]
@@ -3,8 +3,8 @@ from collections.abc import Callable
3
3
  from dataclasses import dataclass
4
4
  from typing import Any, Union
5
5
 
6
+ from fastapi.responses import JSONResponse
6
7
  from pydantic import BaseModel
7
- from starlette.responses import JSONResponse
8
8
 
9
9
  from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
10
10
  from apexdevkit.fastapi.response import RestfulResponse
@@ -1,3 +1,4 @@
1
+ from collections.abc import Callable
1
2
  from dataclasses import dataclass, field
2
3
  from enum import Enum
3
4
  from typing import Annotated, Any, Protocol, Self, TypeVar
@@ -12,6 +13,38 @@ from apexdevkit.fastapi.schema import RestfulSchema, Schema, SchemaFields
12
13
  from apexdevkit.fastapi.service import RawCollection, RawItem, RestfulService
13
14
  from apexdevkit.fluent import FluentDict
14
15
 
16
+
17
+ class RouterWithHiddenUnderscoreRoutes(APIRouter):
18
+ def add_api_route(
19
+ self,
20
+ path: str,
21
+ endpoint: Callable[..., Any],
22
+ **kwargs: Any,
23
+ ) -> None:
24
+ super().add_api_route(path, endpoint, **kwargs)
25
+ self._add_underscored_api_route(path, endpoint, kwargs.copy())
26
+
27
+ def _add_underscored_api_route(
28
+ self,
29
+ path: str,
30
+ endpoint: Callable[..., Any],
31
+ kwargs: dict[str, Any],
32
+ ) -> None:
33
+ if "-" not in path:
34
+ return
35
+
36
+ op_id = kwargs.get("operation_id", endpoint.__name__) or endpoint.__name__
37
+ kwargs["operation_id"] = f"{op_id}_alias"
38
+ kwargs["include_in_schema"] = False
39
+
40
+ # Register the underscored route pointing to the same endpoint
41
+ super().add_api_route(
42
+ path=path.replace("-", "_"),
43
+ endpoint=endpoint,
44
+ **kwargs,
45
+ )
46
+
47
+
15
48
  _Response = JSONResponse | dict[str, Any]
16
49
 
17
50
  T = TypeVar("T")
@@ -27,7 +60,7 @@ class RestfulRouter:
27
60
  name: RestfulName
28
61
 
29
62
  parent: RestfulName | None = None
30
- router: APIRouter = field(default_factory=APIRouter)
63
+ router: APIRouter = field(default_factory=RouterWithHiddenUnderscoreRoutes)
31
64
 
32
65
  _schema: RestfulSchema = field(init=False)
33
66
  _dependency: Dependency | None = field(init=False, default=None)
@@ -1,6 +1,6 @@
1
1
  from .fake import FakeHttp
2
2
  from .fluent import FluentHttp, FluentHttpRequest, FluentHttpResponse, Http, HttpMethod
3
- from .httpx import Httpx, HttpxConfig
3
+ from .httpx import Httpx, HttpxConfig, SignPayloadWith
4
4
  from .json import JsonDict
5
5
  from .url import HttpUrl
6
6
 
@@ -13,6 +13,7 @@ __all__ = [
13
13
  "HttpMethod",
14
14
  "Httpx",
15
15
  "HttpxConfig",
16
+ "SignPayloadWith",
16
17
  "JsonDict",
17
18
  "HttpUrl",
18
19
  ]
@@ -0,0 +1,10 @@
1
+ from .client import Httpx, HttpxConfig
2
+ from .hooks import DefaultHandler, HttpxHandler, SignPayloadWith
3
+
4
+ __all__ = [
5
+ "Httpx",
6
+ "HttpxConfig",
7
+ "SignPayloadWith",
8
+ "DefaultHandler",
9
+ "HttpxHandler",
10
+ ]
@@ -4,6 +4,9 @@ from dataclasses import dataclass
4
4
  from typing import Generic, Protocol, TypeVar
5
5
 
6
6
  import httpx
7
+ from httpx import Request, SyncByteStream
8
+
9
+ from apexdevkit.security import Authority
7
10
 
8
11
  ContextT = TypeVar("ContextT", contravariant=True)
9
12
 
@@ -70,3 +73,13 @@ class AfterResponseHook:
70
73
  self.handler.on_delete(response)
71
74
  case _:
72
75
  pass
76
+
77
+
78
+ @dataclass(frozen=True)
79
+ class SignPayloadWith(DefaultHandler[Request]):
80
+ authority: Authority
81
+
82
+ def on_post(self, context: Request) -> None:
83
+ assert isinstance(context.stream, SyncByteStream)
84
+ signature = self.authority.sign(next(iter(context.stream)).decode())
85
+ context.headers[signature.name] = signature.value
@@ -1,37 +1,33 @@
1
1
  [project]
2
2
  name = "apexdevkit"
3
- version = "1.30.3"
3
+ version = "1.31.1"
4
4
  description = "Apex Development Tools for python."
5
5
  readme = "README.md"
6
6
  authors = [
7
7
  { name = "Apex Dev", email = "dev@apex.ge" }
8
8
  ]
9
9
  dynamic = ["dependencies"]
10
- requires-python = ">=3.11"
10
+ requires-python = ">=3.11,<4"
11
11
 
12
12
  [tool.poetry.dependencies]
13
- httpx = "*"
14
13
  fastapi = "*"
15
- uvicorn = "*"
16
- sentry-sdk = { extras = ["fastapi"], version = "*" }
14
+ httpx = "*"
17
15
  python-dotenv = "*"
18
16
  pymssql = "2.*"
19
- typer = "*"
20
- tomlkit = "*"
17
+ pydantic = "*"
18
+ sentry-sdk = { extras = ["fastapi"], version = "*" }
19
+ uvicorn = "*"
21
20
 
22
21
  [tool.poetry.group.dev.dependencies]
23
- approvaltests = "*"
22
+ apexcodexpy = "0.6.5"
24
23
  pytest = "*"
25
24
  pytest-approvaltests = "*"
26
25
  pytest-cov = "*"
26
+ pytest-env = "*"
27
27
  pytest-recording = "*"
28
28
  coverage = "*"
29
29
  faker = "*"
30
30
 
31
-
32
- [tool.poetry.group.lint.dependencies]
33
- apexcodexpy = "0.4.1"
34
-
35
31
  [tool.mypy]
36
32
  ignore_missing_imports = true
37
33
  strict = true
@@ -42,6 +38,11 @@ exclude = [
42
38
  show_error_codes = true
43
39
  pretty = true
44
40
 
41
+ [tool.deptry]
42
+ extend_exclude = [
43
+ "apexdevkit/testing",
44
+ ]
45
+
45
46
  [tool.ruff.lint]
46
47
  select = [
47
48
  "A",
@@ -80,3 +81,8 @@ source = [
80
81
  skip_empty = true
81
82
  skip_covered = true
82
83
  show_missing = true
84
+
85
+ [tool.pytest]
86
+ env = [
87
+ "ECHO_SERVER=http://httpbin.org"
88
+ ]
@@ -1,6 +0,0 @@
1
- from .client import Httpx, HttpxConfig
2
-
3
- __all__ = [
4
- "Httpx",
5
- "HttpxConfig",
6
- ]
File without changes
File without changes