Confused by conv2d(..) interface

API describes:
https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D

tf.keras.layers.Conv2D(    filters, kernel_size, strides=(1, 1), padding='valid',    data_format=None, dilation_rate=(1, 1), groups=1, activation=None,    use_bias=True, kernel_initializer='glorot_uniform',    bias_initializer='zeros', kernel_regularizer=None,    bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,    bias_constraint=None, **kwargs)

followed by some example:

# The inputs are 28x28 RGB images with `channels_last` and the batch
# size is 4.
input_shape = (4, 28, 28, 3)
x = tf.random.normal(input_shape)
y = tf.keras.layers.Conv2D(
2, 3, activation='relu', input_shape=input_shape[1:])(x)
print(y.shape)

so I am assuming 2 filters, 3x3 kernel size etc.
Now the book I have shows the example specified large number of filters: 128, 64 etc, is it really accurate?

https://www.machinecurve.com/index.php/2020/03/30/how-to-use-conv2d-with-keras/

Secondly, I am also "porting" doing pytorch equivalent but pytorch's conv2d API has no mentions of filters, only significant params are: channels in / out and kernel size:

https://pytorch.org/docs/stable/generated/torch.nn.Dropout.html#torch.nn.Dropout

So how one specifies the filter in pytorch?

Plus I have following example, but when I print out the model, the input shape is 60k, 28, 28.
Then output of first conv2d layer is still 28, 28, how is that possible image is still 28, 28 even went through a kernel size of 7x7?

model=keras.models.Sequential([\
    keras.layers.Conv2D(64, 7, activation="relu", padding="same", input_shape=[28, 28, 1]),\
    keras.layers.MaxPooling2D(2), \


X_train_full.shape:  (60000, 28, 28, 1)
X_train_full.dtype:  uint8
X_test shape:  (10000, 28, 28)
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/init_ops.py:1251: calling VarianceScaling.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d (Conv2D)              (None, 28, 28, 64)        3200
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 14, 14, 64)        0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 14, 14, 128)       73856
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 14, 14, 128)       147584
_________________________________________________________________